概述
这篇文章不涉及源码的解释,不过我相信通过此文章,读者们一定能获得一些东西。
首先我们知道绘制View最基本的三个步骤
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
protected void onLayout(boolean changed, int l, int t, int r, int b)
protected void onDraw(Canvas canvas)
首先想为什么会有这三个步骤?
答:因为你是自定义View,一个View可能需要测量,定位和绘制
想不通也没关系,我们继续往下走(我们以一个绘制九九乘法表为例):
思路:要做九九乘法表,必须先测量孩子节点的宽高然后设置父布局的宽高,当然你也可以给父布局直接定义一个合适的宽高。然后我们想去定位这些节点的位置,如何定位呢?int l, int t, int r, int b,对于这四个参数我们可以这样理解矩形左上角的坐标(l,t),右下角坐标(r,b),所以想想九九乘法表的构造我们可以知道必须测出每个矩形的宽高才能进行定位,所以这里onMeasure是必须的
首先分析onMeasure:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
TextView child;
//通过回调的两个参数widthMeasureSpec,heightMeasureSpec获取父布局的size和模式
//意思就是wrap_parent,match_parent,还有另一种模式就是给定值得模式,这三种模式分
//别对应的Int为UNSPECIFIED = 0, AT_MOST = 2
EXACTLY= 1
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);//已定义好为match_parent
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);//
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);//wrap_parent
int width = 0;
int height = 0;
int childHeight = 0;
int childWidth = 0;
/**
*这里为什么可以得到子视图的数量呢?
*答:因为在MainActivity中就可以看到答案
*/
int count = this.getChildCount();//得到子视图的数量,这里就是81个
for(int i = 0; i < 9; i++){
for(int j = 0; j < j + 1;
j++){
child = (TextView)getChildAt(getLocation(i, j));
child.setWidth(sizeWidth/9);
//此处是测量孩子节点的宽高
measureChild(child, widthMeasureSpec, heightMeasureSpec);
childWidth = child.getMeasuredWidth() ;
// 子View占据的高度
childHeight = child.getMeasuredHeight();
}
height = height + childHeight;
}
//通过孩子节点的宽高可以设置父布局的宽高,这里测量孩子节点的宽高其中的目的就是它
setMeasuredDimension(sizeWidth ,height);
}
下面我们来看onlayout定位
private int getLocation(int i, int j){
int location = 0;
for(int m = i; m > 0; m--){
location = location + m;
}
return location + j;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
TextView child;
for(int i = 0; i < 9; i++){
for(int j = 0; j < i + 1;
j++){
child = (TextView)getChildAt(getLocation(i, j));
int rc = child.getMeasuredWidth();
int bc = child.getMeasuredHeight();
String s = child.getText().toString();
int lc = j * rc;
int tc = i * bc;
child.layout(lc,tc,rc + lc,bc + tc);//左上角和右下角的坐标
}
}
}
public class MainActivity extends Activity {
private TextView[] textViews = new TextView[81];
private MultiplicationTable mt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mt = (MultiplicationTable) findViewById(R.id.mult);
LayoutInflater mInflater = LayoutInflater.from(this);
//在这里执行完后才会绘制view,这里回答了上面提到的问题
for(int i = 0; i < 9; i++){
for(int j = 0; j < i + 1;
j++) {
TextView tv = (TextView) mInflater.inflate(R.layout.tv,
mt, false);
tv.setText((j + 1) + "*" + (i + 1) + "=" + (i + 1) * (j + 1));
tv.setBackgroundColor(Color.RED );
tv.setGravity(Gravity.CENTER);
tv.setTextSize(10);
mt.addView(tv);
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
对于布局不要想太多,一下就足够了
activity_main.xml
<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="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
tools:context=".MainActivity">
<com.vincesheng.myapplication.MultiplicationTable
android:id="@+id/mult"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.vincesheng.myapplication.MultiplicationTable>
</RelativeLayout>
tv.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5BC4ED"
>
</TextView>
最后
以上就是贪玩灰狼为你收集整理的自定义View自己的简单理解的全部内容,希望文章能够帮你解决自定义View自己的简单理解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复