如何在Android中创建圆角列表视图?
如何在Android中创建圆角列表视图?以下是一种方法(感谢Android文档!): 将以下内容添加到文件(比如customshape.xml)中,然后将其放入(res/drawable/customshape.xml)如何在Android中创建圆角列表视图?,android,android-layout,android-listview,Android,Android Layout,Android Listview,如何在Android中创建圆角列表视图?以下是一种方法(感谢Android文档!): 将以下内容添加到文件(比如customshape.xml)中,然后将其放入(res/drawable/customshape.xml) 希望有人会觉得它有用…虽然它确实有用,但它也去掉了整个背景色。我正在寻找一种方法来处理边界,并用这个代码替换XML布局代码,我很乐意去做 <shape xmlns:android="http://schemas.android.com/apk/res/android"&g
希望有人会觉得它有用…虽然它确实有用,但它也去掉了整个背景色。我正在寻找一种方法来处理边界,并用这个代码替换XML布局代码,我很乐意去做
<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>
更新 现在的解决方案是使用内置圆角支持的
CardView
原始答案* 我发现的另一种方法是通过在布局顶部绘制图像来掩盖布局。这可能对你有帮助。查看@kris van bael 对于那些在选择时显示背景矩形的顶行和底行的选择高亮显示有问题的用户,您需要将listview的选择器设置为透明颜色
listView.setSelector(R.color.transparent);
在color.xml中,只需添加以下内容-
<color name="transparent">#00000000</color>
#00000000
实际上,我认为最好的解决方案是在这个链接上描述的:
简言之,它对顶部、中间和底部项目使用不同的背景,因此顶部和底部项目将被舍入 选择的另一个解决方案突出了列表中第一项和最后一项的问题: 在列表背景的顶部和底部添加等于或大于半径的填充。这样可以确保选择高亮显示不会与角点曲线重叠 当您需要不透明的选择高亮显示时,这是最简单的解决方案
<?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>
感谢作者,其他答案非常有用 但我看不出如何在选择时突出显示项目时自定义矩形,而不是禁用突出显示@alvins@bharat dojeha 以下内容可用于创建圆形列表视图项容器,当选择相同形状时,该容器没有轮廓且为浅灰色: 您的xml需要包含选择器,例如(在res/drawable/customshape.xml中): 并且还需要“隐藏”默认选择器矩形,例如在onCreate中(我还隐藏项目之间的灰色细分隔线):
这种方法解决了可绘图项的通用解决方案,而不仅仅是具有各种选择状态的ListViewItem 这对我来说非常方便。如果您正在使用自己的
CustomAdapter
,我想建议另一种解决方法来完美突出圆角
定义XML文件
首先,进入可绘制文件夹,创建4种不同的形状:
- 形状与顶部
shape\u 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>
完成了 要创建边框,您必须在可绘制文件夹中创建另一个具有solid和corners属性的xml文件,并在后台调用它我使用的是一个自定义视图,我将其布局在其他视图的顶部,它仅以与背景相同的颜色绘制4个小角。无论视图内容是什么,它都可以工作,并且不会分配太多内存
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);
}
}
有不同的方法来实现它。最新的方法是对每个ListItem组件使用CardView。 以下是一些步骤
public class ListAdapter extends BaseAdapter {
private ArrayList<RowItem> singleRow;
private LayoutInflater thisInflater;
public ListAdapter(Context context, ArrayList<RowItem> aRow){
this.singleRow = aRow;
thisInflater = ( LayoutInflater.from(context) );
}
@Override
public int getCount() {
return singleRow.size(); }
@Override
public Object getItem(int position) {
return singleRow.get( position ); }
@Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = thisInflater.inflate( R.layout.mylist2, parent, false );
//set listview objects here
//example
TextView titleText = (TextView) view.findViewById(R.id.titleoflistview);
RowItem currentRow = (RowItem) getItem(position);
titleText.setText( currentRow.getHeading() );
}
return view;
// LayoutInflater inflater=.getLayoutInflater();
// View rowView=inflater.inflate(R.layout.mylist, null,true);
//
// titleText.setText(maintitle[position]);
// subtitleText.setText(subtitle[position]);
// return null;
};
}
公共类ListAdapter扩展了BaseAdapter{
私有数组列表单行;
私人停车场,充气机;
公共ListAdapter(上下文上下文,ArrayList aRow){
this.singleRow=aRow;
thisInflater=(LayoutInflater.from(context));
}
@凌驾
public int getCount(){
返回singleRow.size();}
@凌驾
公共对象getItem(int位置){
返回singleRow.get(位置);}
@凌驾
公共长getItemId(int位置){
返回位置;
}
公共视图getView(内部位置、视图视图、视图组父视图){
如果(视图==null){
视图=此充气器。充气(R.layout.mylist2,父项,false);
//在此处设置listview对象
//范例
TextView titleText=(TextView)view.findViewById(R.id.titleoflistview);
RowItem currentRow=(RowItem)getItem(位置);
titleText.setText(currentRow.getHeading());
}
返回视图;
//LayoutInflater充气器=.getLayoutInflater();
//视图行视图=充气机。充气(R.layout.mylist,null,true);
//
//titleText.setText(主标题[职位]);
//subtitleText.setText(副标题[位置]);
//返回null;
};
}
谢谢你的精彩提示。仅供参考,复制粘贴给了我一个运行时异常,它说:“XmlPullParserException:Binary XML file line#4标记要求'angle'属性是45的倍数".. 将角度更改为270即可轻松修复。感谢您的修复。。。但我不知道为什么会这样。。你找到什么具体原因了吗?谢谢你的提示!只是
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//snip
convertView.setBackgroundResource(R.drawable.customshape);
//snip
}
listView.setSelector(android.R.color.transparent);
listview.setDivider(null);
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:bottomRightRadius="10dp"
android:bottomRightRadius="10dp"/>
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomRightRadius="10dp"/>
<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" />
<?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>
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);
}
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);
}
}
**listitem.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alignmentMode="alignMargins"
android:columnCount="1"
android:columnOrderPreserved="false"
android:rowCount="1">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:layout_margin="6dp"
app:cardCornerRadius="8dp"
app:cardElevation="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/sampleiconimageID"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="5dp"/>
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/titleoflistview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Main Heading"
android:textStyle="bold" />
<TextView
android:id="@+id/samplesubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sub Heading"
/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</GridLayout>
</LinearLayout>
public class RowItem {
private String heading;
private String subHeading;
private int smallImageName;
private String datetime;
private int count;
public void setHeading( String theHeading ) {
this.heading = theHeading;
}
public String getHeading() {
return this.heading;
}
public void setSubHeading( String theSubHeading ) {
this.subHeading = theSubHeading;
}
public String getSubHeading( ) {
return this.subHeading;
}
public void setSmallImageName(int smallName) {
this.smallImageName = smallName;
}
public int getSmallImageName() {
return this.smallImageName;
}
public void setDate(String datetime) {
this.datetime = datetime;
}
public String getDate() {
return this.datetime;
}
public void setCount(int count) {
this.count = count;
}
public int getCount() {
return this.count;
}
}
public class ListAdapter extends BaseAdapter {
private ArrayList<RowItem> singleRow;
private LayoutInflater thisInflater;
public ListAdapter(Context context, ArrayList<RowItem> aRow){
this.singleRow = aRow;
thisInflater = ( LayoutInflater.from(context) );
}
@Override
public int getCount() {
return singleRow.size(); }
@Override
public Object getItem(int position) {
return singleRow.get( position ); }
@Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = thisInflater.inflate( R.layout.mylist2, parent, false );
//set listview objects here
//example
TextView titleText = (TextView) view.findViewById(R.id.titleoflistview);
RowItem currentRow = (RowItem) getItem(position);
titleText.setText( currentRow.getHeading() );
}
return view;
// LayoutInflater inflater=.getLayoutInflater();
// View rowView=inflater.inflate(R.layout.mylist, null,true);
//
// titleText.setText(maintitle[position]);
// subtitleText.setText(subtitle[position]);
// return null;
};
}