相信不少童鞋都在为定义圆角图片而苦恼,这里我们提供了一个圆角相对布局比起圆角图片复用性更好,能嵌套任何想变成圆角的内容,处理也是相当简单的下面来看代码处理。
/**
* 作用:圆角相对布局
* 作者:KangJH
*/
public class RCRelativeLayout extends RelativeLayout {
public float[] radii = {0, 0, 0, 0, 0, 0, 0, 0}; // top-left, top-right, bottom-right, bottom-left
public Path mClipPath; // 剪裁区域路径
public Paint mPaint; // 画笔
public int mEdgeFix = 10; // 边缘修复
public RectF mLayer; // 画布图层大小
public RCRelativeLayout(Context context) {
this(context, null);
}
public RCRelativeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RCRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLayer = new RectF();
mClipPath = new Path();
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
}
@Override//当调用invalidate的时候会首先调用该处理
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mLayer.set(0, 0, w, h);
refreshRegion();
}
@Override//系统方法替代viewgroup的draw
protected void dispatchDraw(Canvas canvas) {
canvas.saveLayer(mLayer, null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawPath(mClipPath, mPaint);
canvas.restore();
}
@Override//在设置背景的情况下会调用draw方法 或者设置willnotdraw为false会调用因此要添加切割背景的处理
public void draw(Canvas canvas) {
refreshRegion();
canvas.save();
canvas.clipPath(mClipPath);
super.draw(canvas);
canvas.restore();
}
public void refreshRegion() {
int w = (int) mLayer.width();
int h = (int) mLayer.height();
mClipPath.reset();
mClipPath.addRoundRect(new RectF(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom()), radii, Path.Direction.CW);
mClipPath.moveTo(-mEdgeFix, -mEdgeFix); // 通过空操作让Path区域占满画布
mClipPath.moveTo(w + mEdgeFix, h + mEdgeFix);
}
public void setRadius(int radius) {
for (int i = 0; i < radii.length; i++) {
radii[i] = radius;
}
invalidate();
}
}
对外调用的处理就一个setRadius当然大家如果想添加其他处理可以向外添加方法这里我只讲最简单最核心的处理。
构造方法里面的初始化就不做过多介绍了,大家应该都明白。
当调用invalidate方法是我们首先调用的是onSizeChanged方法,refreshRegion处理是通过path划出圆角矩形的轮廓,mClipPath.moveTo的处理很关键没有这两行zailistview快速滑动过程中可能会导致有些圆角首先展示直角然后逐渐变为圆角。
如果没有设置背景之后会调用dispatchDraw处理将path画到画布上,如果有背景会调用draw这里的处理是将背景切割保证背景也是圆角的。
下面就是外部的调用,也是十分简单代码如下
public class MainActivity extends AppCompatActivity {
private ListView lv_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv_main = findViewById(R.id.lv_main);
List aas = new ArrayList<>();
for (int i = 0; i < 100; i++) {
aas.add("sss");
}
lv_main.setAdapter(new MyAdapter(aas));
}
class MyAdapter extends BaseAdapter {
private List datas;
public MyAdapter(List datas) {
this.datas = datas;
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return datas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
@SuppressLint("ViewHolder") View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_rount_rect, null);
RCRelativeLayout rc_rl = view.findViewById(R.id.rc_rl);
rc_rl.setRadius(30);
return view;
}
}
}
下面是item的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.example.pc_304.testrrelativelayout.RCRelativeLayout
android:id="@+id/rc_rl"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:background="#ffffff">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/download"
android:contentDescription="@string/app_name" />
com.example.pc_304.testrrelativelayout.RCRelativeLayout>
RelativeLayout>
主界面布局如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.pc_304.testrrelativelayout.MainActivity">
<ListView
android:id="@+id/lv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
RelativeLayout>
怎么样是不是很简单。