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)文章
Android實(shí)現(xiàn)按鈕點(diǎn)擊事件的三種方法總結(jié)
Button是程序用于和用戶進(jìn)行交互的一個(gè)重要控件。既然有Button,那肯定有onClick方法,下面就教大家三種實(shí)現(xiàn)點(diǎn)擊事件的方法,感興趣的可以了解一下2022-04-04
Android?使用flow實(shí)現(xiàn)倒計(jì)時(shí)的方式
這篇文章主要介紹了Android?使用flow實(shí)現(xiàn)倒計(jì)時(shí)的方式,借助Flow這個(gè)工具,更加優(yōu)雅地實(shí)現(xiàn)這個(gè)需求功能,文末給大家整理了Android?實(shí)現(xiàn)倒計(jì)時(shí)的幾種方式,需要的朋友可以參考下2022-04-04
三行Android代碼實(shí)現(xiàn)白天夜間模式流暢切換
這篇文章主要為大家分享了三行Android代碼實(shí)現(xiàn)白天夜間模式流暢切換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Activit跳轉(zhuǎn)動(dòng)畫之界面上某個(gè)位置并裂開(kāi)上下拉伸動(dòng)畫跳轉(zhuǎn)
這篇文章主要介紹了Activit跳轉(zhuǎn)動(dòng)畫之界面上某個(gè)位置并裂開(kāi)上下拉伸動(dòng)畫跳轉(zhuǎn)的相關(guān)資料,需要的朋友可以參考下2016-07-07
Android Studio升級(jí)4.1.1后各種錯(cuò)誤和解決方案
這篇文章主要介紹了Android Studio升級(jí)4.1.1后各種錯(cuò)誤和解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Android ViewPager實(shí)現(xiàn)動(dòng)畫切換效果
這篇文章主要為大家詳細(xì)介紹了Android ViewPager實(shí)現(xiàn)動(dòng)畫切換效果的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
android常見(jiàn)手動(dòng)和自動(dòng)輪播圖效果
這篇文章主要為大家詳細(xì)介紹了android常見(jiàn)手動(dòng)和自動(dòng)輪播圖效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Android UI控件RatingBar實(shí)現(xiàn)自定義星星評(píng)分效果
這篇文章主要為大家詳細(xì)介紹了Android UI控件RatingBar實(shí)現(xiàn)自定義星星評(píng)分效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
Android實(shí)現(xiàn)一個(gè)完美的倒計(jì)時(shí)功能
在Adroid應(yīng)用中,倒計(jì)時(shí)的功能使用的很多,例如點(diǎn)擊獲取短信驗(yàn)證碼之后的倒計(jì)時(shí)等等,這篇文章主要給大家介紹了關(guān)于利用Android如何實(shí)現(xiàn)一個(gè)完美的倒計(jì)時(shí)功能的相關(guān)資料,需要的朋友可以參考下2021-11-11

