Làm cách nào để tạo ListView với các góc tròn trong Android?
Làm cách nào để tạo ListView với các góc tròn trong Android?
Câu trả lời:
Đây là một cách để làm điều đó (Nhờ Tài liệu Android!):
Thêm phần sau vào một tệp (giả sử customshape.xml) và sau đó đặt tệp đó vào (res / drawable / customshape.xml)
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#SomeGradientBeginColor"
android:endColor="#SomeGradientEndColor"
android:angle="270"/>
<corners
android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
Khi bạn đã hoàn tất việc tạo tệp này, chỉ cần đặt nền theo một trong các cách sau:
Thông qua mã:
listView.setBackgroundResource(R.drawable.customshape);
Thông qua XML , chỉ cần thêm thuộc tính sau vào vùng chứa (ví dụ: linearLayout hoặc vào bất kỳ trường nào):
android:background="@drawable/customshape"
Hy vọng ai đó thấy nó hữu ích ...
Mặc dù điều đó đã làm việc, nó cũng lấy ra toàn bộ màu nền. Tôi đang tìm cách để chỉ làm đường viền và chỉ cần thay thế mã bố cục XML đó bằng mã này và tôi đã rất tốt để đi!
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="4dp" android:color="#FF00FF00" />
<padding android:left="7dp" android:top="7dp"
android:right="7dp" android:bottom="7dp" />
<corners android:radius="4dp" />
</shape>
@ kris-van-bael
Đối với những người có vấn đề với tô sáng lựa chọn cho hàng trên cùng và dưới cùng, nơi hình chữ nhật nền hiển thị trên vùng chọn, bạn cần đặt bộ chọn cho chế độ xem của bạn thành màu trong suốt.
listView.setSelector(R.color.transparent);
Trong color.xml chỉ cần thêm vào như sau -
<color name="transparent">#00000000</color>
android:cacheColorHint="@android:color/transparent"
Các câu trả lời khác rất hữu ích, nhờ các tác giả!
Nhưng tôi không thể thấy cách tùy chỉnh hình chữ nhật khi làm nổi bật một mục khi lựa chọn thay vì vô hiệu hóa phần tô sáng @alvins @bharat dojeha.
Các công việc sau đây để tôi tạo một thùng chứa mục xem danh sách tròn không có viền ngoài và màu xám nhạt hơn khi được chọn có cùng hình dạng:
Xml của bạn cần chứa một bộ chọn, ví dụ: (trong res / drawable / customshape.xml):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="8dp" android:color="@android:color/transparent" />
<padding android:left="14dp" android:top="14dp"
android:right="14dp" android:bottom="14dp" />
<corners android:radius="10dp" />
<gradient
android:startColor="@android:color/background_light"
android:endColor="@android:color/transparent"
android:angle="225"/>
</shape>
</item>
<item android:state_pressed="false">
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="8dp" android:color="@android:color/transparent" />
<padding android:left="14dp" android:top="14dp"
android:right="14dp" android:bottom="14dp" />
<corners android:radius="10dp" />
<gradient
android:startColor="@android:color/darker_gray"
android:endColor="@android:color/transparent"
android:angle="225"/>
</shape>
</item>
Sau đó, bạn cần triển khai bộ điều hợp danh sách và ghi đè phương thức getView để đặt bộ chọn tùy chỉnh làm nền
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//snip
convertView.setBackgroundResource(R.drawable.customshape);
//snip
}
và cũng cần 'ẩn' hình chữ nhật của bộ chọn mặc định, ví dụ như trong onCreate (Tôi cũng ẩn dòng chia màu xám mỏng giữa các mục):
listView.setSelector(android.R.color.transparent);
listview.setDivider(null);
Cách tiếp cận này giải quyết một giải pháp chung cho các drawable, không chỉ ListViewItem với các trạng thái lựa chọn khác nhau.
Cập nhật
Giải pháp hiện nay là sử dụng CardView
hỗ trợ cho các góc tròn được tích hợp sẵn.
Câu trả lời gốc *
Một cách khác tôi tìm thấy là che giấu bố cục của bạn bằng cách vẽ một hình ảnh trên đầu bố cục. Nó có thể giúp bạn. Kiểm tra các góc được cắt tròn của Android XML
Một giải pháp khác để lựa chọn làm nổi bật các vấn đề với các mục đầu tiên và cuối cùng trong danh sách:
Thêm phần đệm vào trên cùng và dưới cùng của nền danh sách của bạn bằng hoặc lớn hơn bán kính. Điều này đảm bảo việc tô sáng vùng chọn không trùng với các đường cong góc của bạn.
Đây là giải pháp đơn giản nhất khi bạn cần làm nổi bật lựa chọn không minh bạch.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="@color/listbg" />
<stroke
android:width="2dip"
android:color="#D5D5D5" />
<corners android:radius="10dip" />
<!-- Make sure bottom and top padding match corner radius -->
<padding
android:bottom="10dip"
android:left="2dip"
android:right="2dip"
android:top="10dip" />
</shape>
Trên thực tế, tôi nghĩ rằng giải pháp tốt nhất được mô tả trên liên kết này:
http://blog.synyx.de/2011/11/android-listview-with-rounded-corners/
Nói tóm lại, nó sử dụng một nền tảng khác nhau cho các mục trên cùng, giữa và dưới cùng, để các mục trên cùng và dưới cùng sẽ được làm tròn.
Điều này là vô cùng tiện dụng với tôi. Tôi muốn đề xuất một cách giải quyết khác để làm nổi bật hoàn hảo các góc tròn nếu bạn đang sử dụng của riêng bạn CustomAdapter
.
Trước hết, hãy vào trong thư mục có thể vẽ của bạn và tạo 4 hình dạng khác nhau:
hình dạng
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
hình dạng bất thường
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
hình dạng_bottom
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:bottomRightRadius="10dp"
android:bottomRightRadius="10dp"/>
hình dạng_rounded
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomRightRadius="10dp"/>
Bây giờ, tạo một bố cục hàng khác nhau cho mỗi hình dạng, tức là cho shape_top
:
Bạn cũng có thể làm điều này theo chương trình thay đổi nền.
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
android:fontFamily="sans-serif-light"
android:text="TextView"
android:textSize="22dp" />
<TextView
android:id="@+id/txtValue1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:textSize="22dp"
android:layout_gravity="right|center"
android:gravity="center|right"
android:layout_marginLeft="20dp"
android:layout_marginRight="35dp"
android:text="Fix"
android:scaleType="fitEnd" />
Và xác định một bộ chọn cho mỗi danh sách hình, tức là cho shape_top
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selected Item -->
<item android:state_selected="true"
android:drawable="@drawable/shape_top" />
<item android:state_activated="true"
android:drawable="@drawable/shape_top" />
<!-- Default Item -->
<item android:state_selected="false"
android:drawable="@android:color/transparent" />
</selector>
Cuối cùng, xác định các tùy chọn bố trí bên trong CustomAdapter
:
if(position==0)
{
convertView = mInflater.inflate(R.layout.list_layout_top, null);
}
else
{
convertView = mInflater.inflate(R.layout.list_layout_normal, null);
}
if(position==getCount()-1)
{
convertView = mInflater.inflate(R.layout.list_layout_bottom, null);
}
if(getCount()==1)
{
convertView = mInflater.inflate(R.layout.list_layout_unique, null);
}
Và thế là xong!
để tạo đường viền, bạn phải tạo một tệp xml khác có thuộc tính solid và angle trong thư mục drawable và gọi nó ở chế độ nền
Tôi đang sử dụng chế độ xem tùy chỉnh mà tôi bố trí trên các chế độ khác và chỉ vẽ 4 góc nhỏ cùng màu với nền. Điều này hoạt động cho dù nội dung xem là gì và không phân bổ nhiều bộ nhớ.
public class RoundedCornersView extends View {
private float mRadius;
private int mColor = Color.WHITE;
private Paint mPaint;
private Path mPath;
public RoundedCornersView(Context context) {
super(context);
init();
}
public RoundedCornersView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.RoundedCornersView,
0, 0);
try {
setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
} finally {
a.recycle();
}
}
private void init() {
setColor(mColor);
setRadius(mRadius);
}
private void setColor(int color) {
mColor = color;
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
invalidate();
}
private void setRadius(float radius) {
mRadius = radius;
RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
mPath = new Path();
mPath.moveTo(0,0);
mPath.lineTo(0, mRadius);
mPath.arcTo(r, 180, 90);
mPath.lineTo(0,0);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
/*Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(0, 0, mRadius, mRadius, paint);*/
int w = getWidth();
int h = getHeight();
canvas.drawPath(mPath, mPaint);
canvas.save();
canvas.translate(w, 0);
canvas.rotate(90);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.save();
canvas.translate(w, h);
canvas.rotate(180);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.translate(0, h);
canvas.rotate(270);
canvas.drawPath(mPath, mPaint);
}
}