自定义ViewGroup形状

  • 重写ViewGroup的 dispatchDraw方法
  • 行使 Paint 的setXfermode方法,依照path的造型绘制出分裂造型图案的机能
  • 只替换种种形态的path就可绘制出各样形象

阐明:参考了部分网络的各样完结格局,那个是相比较好的贯彻情势

图片 1device-2017-08-20-131344.png

github 地址xml

 <com.example.ck.shapelayout.RadiusRelativelayout android:layout_width="250dp" android:layout_height="250dp" android:layout_centerInParent="true" app:corner_radius="50dp"> <ImageView android:layout_width="250dp" android:layout_height="250dp" android:background="#f00" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" /> </com.example.ck.shapelayout.RadiusRelativelayout>

public class RadiusRelativelayout extends RelativeLayout { private float cornerRadius; private Path path; public RadiusRelativelayout(Context context) { this(context, null); } public RadiusRelativelayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RadiusRelativelayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RadiusRelativelayout); ; try { cornerRadius = typedArray.getDimension(R.styleable.RadiusRelativelayout_corner_radius, 0); } catch (Exception e) { e.printStackTrace(); } finally { typedArray.recycle(); } } public RadiusRelativelayout setPath(Path path) { this.path = path; invalidate(); return this; } @Override protected void dispatchDraw(Canvas canvas) { //无设置空 if (path == null && cornerRadius == 0) { super.dispatchDraw; return; } /** * @path 要显示的形状 * 未设置path 设置了园角度 */ if (path == null) { path = new Path(); path.addRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight, cornerRadius, cornerRadius, Path.Direction.CCW); } /** * 抗锯齿 */ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //保存图层 int save = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG); super.dispatchDraw; paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); canvas.drawPath(path, paint); canvas.restoreToCount; paint.setXfermode; }}
  • 初识 ViewRoot 和 DecorView;
  • 理解 MeasureSpec;
  • View 的做事流程:measure、layout、draw。

转发请标注出处:

图片 2hello,夏天

骨子里开支中,社交或然市廛类,音讯类的app,超越十分之五的页面都是列表.

为越来越好的理解 View
的三大流程(measurelayoutdraw),先明白一些中坚的定义。

写列表adapter的快慢,基本调控整个app的花费速度.

ViewRoot 对应于 ViewRootImpl 类,是连接 WindowManager
DecorView 的火热,View 的三大流程皆以通过 ViewRoot 来完毕的。

还记得刚做安卓的时候,写listview的adpater,写三个列表写一清晨.几乎丧心病狂.

View 的绘图流程从 ViewRootperformTraversals 方法初步,它经过
measure(测量 View 的宽高),layout(鲜明 View 在父容器的地点) 和
draw(担负将 View 绘制在显示器上) 多少个经过本事将七个 View
绘制出来,如下:

从此出现了RecyclerView,还会有一大批判能够的开源艾达pter.代码已经很便利了.

图片 3performTraversals
的行事流程

而是,在做多少个连串时,分裂的列表只怕会现出有的重新,靠写adapter来复用就搞不定了。再例如,复杂的多type列表照旧会并发大多行代码在onBindViewHolder里面包车型客车情事,维护不易。

DecorView 是一个 FrameLayout,View 层的风云都先经过
DecorView,再传递给 View。

最先始目标,仅仅是为着化解一种类折叠列表.

DecorView 作为头等 View,一般它当中会含有三个竖直方向的
LinearLayout,上边是标题栏,上边是内容栏。在 Activity 中通过
setContentView 设置的布局文件正是被加到内容栏中,而内容栏的 id 为
content,可透过 ViewGroup content = findviewbyid(android.R.id.content)
得到 content,通过 content.getChildAt 得到设置的 View。其协会如下:

传送门:多少个RecyclerView完成多种折叠列表传送门:贰个RecyclerView完成多种折叠列表

图片 4顶级
View:DecorView 的结构

但是创新到今日,TreeRecyclerView这一个名字其实早已不适合了.

MeasureSpec 相当的大程度上调控了壹个 View 的尺码规格。在 View
的度量进程中,系统会将 View 的 LayoutParams
依照父容器所施加的平整调换到对应的 MeasureSpec,再依照那一个
measureSpec 来衡量出 View 的宽高(衡量宽高不鲜明等于 View
的末段宽高
)。

乘机具体应用,更新优化,我意识RecyclerView的Adapter能够换种怀想,换个写法.

MeasureSpec 代表三个三11个人 int 值,高两位表示 SpecMode,低34位表示
SpecSize(有个别度量格局下的标准化大小),MeasureSpec
内部的有的常量定义如下:

为了方便阅读,下文少禽用item来表示列表的条文。

private static final int MODE_SHIFT = 30;private static final int MODE_MASK = 0x3 << MODE_SHIFT;public static final int UNSPECIFIED = 0 << MODE_SHIFT;public static final int EXACTLY = 1 << MODE_SHIFT;public static final int AT_MOST = 2 << MODE_SHIFT;// MeasureSpec通过将SpecMode和SpecSize打包成一个int值来避免过多的对象内存分配public static int makeMeasureSpec(int size, int mode) { if (sUseBrokenMakeMeasureSpec) { return size + mode; } else { return (size & ~MODE_MASK) | (mode & MODE_MASK); }}// 解包:获取其原始的 SpecMode@MeasureSpecModepublic static int getMode(int measureSpec) { return (measureSpec & MODE_MASK);}// 解包:获取其原始的 SpecSizepublic static int getSize(int measureSpec) { return (measureSpec & ~MODE_MASK);}

以下个人见解

SpecMode 有三类,其意义分别如下:

M:塞给adapter的list数据便是modle

发表评论

电子邮件地址不会被公开。 必填项已用*标注