android自定義view用path畫長(zhǎng)方形
這次主要是練習(xí)一下Android的自定義view和path的相關(guān)使用,所以做了一個(gè)簡(jiǎn)單的demo:自定義一個(gè)view,并用path在上面畫一個(gè)可以動(dòng)態(tài)改變圓角大小的長(zhǎng)方形。
自定義相關(guān)屬性
自定義view首先需要在values文件夾下建一個(gè)attrs文件,并在其中定義view的相關(guān)屬性,如下:
<resources>
<declare-styleable name="CustomView">
<attr name="round_position">
<flag name="left-top" value="0x1"></flag>
<flag name="right-top" value="0x4"></flag>
<flag name="left-bottom" value="0x2"></flag>
<flag name="right-bottom" value="0x8"></flag>
</attr>
<attr name="round_radius" format="dimension"></attr>
</declare-styleable>
</resources>
其中round_position指的是圓角的位置,這里屬性類型定為flag(位或運(yùn)算)這樣就可以在布局中同時(shí)使用多個(gè)屬性了,類似于EditText中定義文字樣式:android:textStyle="bold|italic";round_radius指圓角大小,類型為dimension。
自定義view類
新建一個(gè)類繼承View,如下:
public class CustomView extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path path;
private int color = Color.GREEN;
private final int LEFT_TOP = 0x1;
private final int LEFT_BOTTOM = 0x2;
private final int RIGHT_TOP = 0x4;
private final int RIGHT_BOTTOM = 0x8;
private boolean drawLeftTop;
private boolean drawLeftBottom;
private boolean drawRightTop;
private boolean drawRightBottom;
private float radius;
public CustomView(Context context) {
super(context);
initDraw();
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
int position = typedArray.getInt(R.styleable.CustomView_round_position, 0);
radius = typedArray.getDimension(R.styleable.CustomView_round_radius, 0);
drawLeftTop = (position & LEFT_TOP) == LEFT_TOP;
drawLeftBottom = (position & LEFT_BOTTOM) == LEFT_BOTTOM;
drawRightTop = (position & RIGHT_TOP) == RIGHT_TOP;
drawRightBottom = (position & RIGHT_BOTTOM) == RIGHT_BOTTOM;
typedArray.recycle();
initDraw();
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initDraw();
}
private void initDraw() {
path = new Path();
paint.setColor(Color.GREEN);
paint.setAntiAlias(true);
paint.setStrokeWidth((float) 5);
paint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
path.reset();//這里很重要,如果不寫這一行,則每次重繪view后先前繪制的還會(huì)存在
path.moveTo(radius, 0);
if (drawRightTop) {
path.lineTo(getWidth() - radius, 0);
// path.cubicTo(radius + getWidth() / 3, 0, radius + getWidth() / 3 * 2, 0, getWidth() - radius, 0);
path.cubicTo(getWidth() - radius / 2, 0, getWidth(), radius / 2, getWidth(), radius);
} else {
path.lineTo(getWidth(), 0);
// path.cubicTo(radius + getWidth() / 3, 0, radius + getWidth() / 3 * 2, 0, getWidth(), 0);
}
path.lineTo(getWidth(), getHeight() - radius);
// path.cubicTo(getWidth(), radius + getHeight() / 3, getWidth(), radius + getHeight() / 3 * 2, getWidth(), getHeight() - radius);
if (drawRightBottom) {
path.cubicTo(getWidth(), getHeight() - radius / 2, getWidth() - radius / 2, getHeight(), getWidth() - radius, getHeight());
} else {
path.lineTo(getWidth(), getHeight());
}
path.lineTo(radius, getHeight());
if (drawLeftBottom) {
path.cubicTo(radius / 2, getHeight(), 0, getHeight() - radius / 2, 0, getHeight() - radius);
} else {
path.lineTo(0, getHeight());
}
path.lineTo(0, radius);
if (drawLeftTop) {
path.cubicTo(0, radius / 2, radius / 2, 0, radius, 0);
} else {
path.lineTo(0, 0);
path.lineTo(radius, 0);
}
canvas.drawPath(path, paint);
super.onDraw(canvas);
}
public void setRadius(float radius) {
this.radius = radius;
}
public void refreshView() {
invalidate();
}
}
這里使用了path和貝塞爾曲線的繪制方法來(lái)繪制可動(dòng)態(tài)調(diào)整圓角大小的長(zhǎng)方形,注意每次重繪時(shí)要先調(diào)用path.reset()清除之前繪制的path,然后再繪制新的path,不然舊的path還會(huì)一直存在。
布局中使用自定義view
<wjc.myrecyclerview.CustomView
android:id="@+id/custom_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_margin="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:round_position="left-bottom|right-bottom|right-top|left-top" />
這樣就完成了一個(gè)簡(jiǎn)單的自定義可調(diào)整圓角的長(zhǎng)方形,在MainActivity中進(jìn)行動(dòng)態(tài)控制:
view.setRadius(progress); view.refreshView();
實(shí)現(xiàn)的最終效果

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Flexbox+ReclyclerView實(shí)現(xiàn)流式布局
這篇文章主要為大家詳細(xì)介紹了Flexbox+ReclyclerView實(shí)現(xiàn)流式布局,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
Android之獲取手機(jī)內(nèi)部及sdcard存儲(chǔ)空間的方法
今天小編就為大家分享一篇Android之獲取手機(jī)內(nèi)部及sdcard存儲(chǔ)空間的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Android編程自定義title bar(標(biāo)題欄)示例
這篇文章主要介紹了Android編程自定義title bar(標(biāo)題欄)的方法,結(jié)合實(shí)例形式分析了Android針對(duì)標(biāo)題欄的設(shè)置與頁(yè)面布局操作相關(guān)技巧,需要的朋友可以參考下2016-10-10
Android 5.0中CoordinatorLayout的使用技巧
這篇文章主要為大家詳細(xì)介紹了Android 5.0中CoordinatorLayout的使用技巧,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Android 動(dòng)態(tài)加載二維碼視圖生成快照的示例
本篇文章主要介紹了Android 動(dòng)態(tài)加載二維碼視圖生成快照的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
Android App啟動(dòng)圖啟動(dòng)界面(Splash)的簡(jiǎn)單實(shí)現(xiàn)代碼
這篇文章主要介紹了Android App啟動(dòng)圖啟動(dòng)界面(Splash)的簡(jiǎn)單實(shí)現(xiàn)代碼,本文通過(guò)實(shí)例圖文詳解相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
android 監(jiān)聽(tīng)SD卡文件變化的實(shí)現(xiàn)代碼
這篇文章主要介紹了android 監(jiān)聽(tīng)SD卡文件變化的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-11-11
Android學(xué)習(xí)之AppWidget筆記分享
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)筆記之AppWidget的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-08-08

