3.1 自定义控件
3.1.1 基本知识
dp sp px
inflater如何使用
Layoutinflater将xml文件解析成实际的视图view
获得Layoutinflater 的三种方式
Layoutinflater mlayoutinflater=get Layoutinflater();
Layoutinflater mlayoutinflater=getSystemService(LAYOUT_INFLATER_SERVICE);
Layoutinflater mlayoutinflater=Layoutinflater .f(context);
获得后如何转换成View
Mlayoutinflater .inflater( , );
如何把变量变成全局?(快捷方式)
Ctrl+p 查看参数
ALT+ENTER 自动修正,导入当前包
Ctrl+alt+空格 或 ctri+shift+空格代码助手,自动补全
Ctrl+alt+o 删除没用的包
Ctrl+o 快速重写方
ctrl + alt + F将变量变成全局变量的快捷键
shift+f6 重构
Ctrl + Shift + A 查找
Alt + Q 查找上下文信息
Ctrl + D 行复制
提取布局的共同属性(theme & style)
3.1.2 View 是如何工作的
构造器---初始化
onMesure() 定大小
onLayout() 定位置
onDraw() 绘制
invalidate()刷新
3.1.3 实例创建步骤
继承已有的控件来实现自定义控件
继承一个布局文件来实现自定义控件
继承View类来实现自定义控件
案例: 一个简单的自定义控件:圆形红色按钮。中间是白色的数字。数字起始为20,点击一次减少1。
/** * 一个简单的自定义控件:圆形红色按钮。中间是白色的数字。数字起始为20,点击一次减少1。 * Created by Administrator on 2016/5/19. */ public class textRedButton extends View implements View.OnClickListener{ private Paint mPaint; private Rect mRect; private int mNumber=20; public textRedButton(Context context) { this(context, null); } public textRedButton(Context context, AttributeSet attrs) { this(context, attrs, 0); } public textRedButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } /* *init the view */ private void init() { mPaint = new Paint(); mRect = new Rect(); this.setOnClickListener(this); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布为红的 //绘制一个圆形的按钮 mPaint.setColor(Color.RED); canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, mPaint); //中间是白色的字 mPaint.setColor(Color.WHITE); mPaint.setTextSize(60); String text = String.valueOf(mNumber); mPaint.getTextBounds(text, 0, text.length(), mRect); int textwidth = mRect.width(); int textheight = mRect.height(); canvas.drawText(text,getWidth() / 2-textwidth/2,getHeight()/2+textheight/2,mPaint); } @Override public void onClick(View v) { mNumber--; if(mNumber<0) mNumber=20; invalidate(); } }
在布局文件中添加控件
<demo.view.fxc.myviewdemo.textRedButton android:layout_width="200dp" android:layout_height="200dp"/>
3.1.4 如何自定义视图属性
在哪里创建属性
在values中创建文件attrs.xml
如何创建属性
<declare-styleable name="textRedButton"> <attr name="backgroundColor" format="color"> </attr> </declare-styleable>
如何使用这些属性(代码中引用,布局中设置)
代码中引用:
private int mBackgroundColor;
在构造方法中
TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.textRedButton); mBackgroundColor=typedArray.getColor(R.styleable.textRedButton_backgroundColor,Color.BLUE);
在初始化方法中
mPaint.setColor(mBackgroundColor);
布局中设置
//定义命名空间
xmlns:app="http://schemas.android.com/apk/res-auto"
//设置属性间
app:backgroundColor="@color/red"
3.2 Fragment
什么是Fragment?
为什么用Fragmen?
如何使用Fragment?
如何管理Fragment ?
Fragment生命周期?
3.3 有用的Handler
3.3.1 基本概念
多线程与异步通信
什么是Handler
用来做什么?
定时执行message Runnable
在不同线程中执行
Message :消息(2个int 1个object 1个What)
Message queue:消息队列
Looper:
3.3.2 案例实现
实现一个倒计时的按钮
private TextView mText_handle; Handler mHandler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //接受消息 switch(msg.what) { case 888888: int value = (int) msg.obj; mText_handle.setText(String.valueOf(value/1000)); msg=Message.obtain(); msg.arg1=0; msg.arg2=2; msg.what=888888; msg.obj=value-1000; if(value>0){ sendMessageDelayed(msg,1000); } }
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //发送消息 mText_handle = (TextView) findViewById(R.id.text_handle); Message msg=mHandler.obtainMessage(); msg.arg1=0; msg.arg2=2; msg.what=888888; msg.obj=10000; mHandler.sendMessageDelayed(msg,1000); }
优化代码,防止内存泄漏
方法二:
public class MainActivity extends AppCompatActivity { private TextView mText_handle; private TestHandle mTestHandle=new TestHandle(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //发送消息 mText_handle = (TextView) findViewById(R.id.text_handle); Message msg=mTestHandle.obtainMessage(); msg.arg1=0; msg.arg2=2; msg.what=888888; msg.obj=10000; mTestHandle.sendMessageDelayed(msg,1000); } public TextView getText_handle() { return mText_handle; } public class TestHandle extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); //接受消息 switch (msg.what) { case 888888: int value = (int) msg.obj; mText_handle.setText(String.valueOf(value / 1000)); msg = Message.obtain(); msg.arg1 = 0; msg.arg2 = 2; msg.what = 888888; msg.obj = value - 1000; if (value > 0) { sendMessageDelayed(msg, 1000); } } } } }