第三周的内容Fragment,Handler,自定义View。每一个都很重要,需要长时间的学习。其实每一个都不是一篇博客可以写清楚,所以这篇博客简单介绍,然后主要介绍下Fragment.
1.自定义控件,自己绘制一个控件。首先就是新建类去继承View,实现构造方法。新建一个Paint对象,然后使用这个对象可以设置很多东西。最后用canvas画出来,图形有正方形,圆,椭圆,长方形,圆弧,三角形等等。
Paint的方法
// 消除锯齿
paint.setAntiAlias(true);
// 设置画笔的颜色
paint.setColor(Color.RED);
// 设置空心的边框宽度
paint.setStrokeWidth(2);
// 用于设置Paint 的透明度
paint.setAlpha(int a);
//设置画笔风格,空心或者实心
paint.setStyle();
//设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
paint.setDither(boolean dither);
Canvas的方法
// 1、画一个点
mCanvas.drawPoint(23, 23, mPaint) ;
// 2、画线
mCanvas.drawLine(...) ;
//3、画长方形
Rect r = new Rect(10,10,50,50) ;
mCanvas.drawRect(r, mPaint) ;
// 4、画椭圆 初始化RectF的参数是(left,top,right,bottom)
RectF rf = new RectF(100,100 ,200 ,250) ;
mCanvas.drawOval(rf, mPaint) ;
// 5、画圆 (圆心x0,圆心y0,半径,paint)
mCanvas.drawCircle(100, 100, 50, mPaint) ;
2.Handler
Message对象封装了所有的消息,而这些消息的操作需要android.os.Handler类完成。什么是handler?handler起到了处理MQ上的消息的作用(只处理由自己发出的消息),即通知MQ它要执行一个任务(sendMessage),并在loop到自己的时候执行该任务(handleMessage),整个过程是异步的。handler创建时会关联一个looper,默认的构造方法将关联当前线程的looper,不过这也是可以set的。
Handler中分发消息的一些方法
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
一个线程可以有多个Handler,但是只能有一个Looper!
Handler的流程
从这个图中我们很清楚可以看到调用sendEmptyMessage后,会把 Message对象放入一个MessageQueue队列,该队列属于某个Looper对象,每个Looper对象通过 ThreadLocal.set(new Looper())跟一个Thread绑定了,Looper对象所属的线程在Looper.Loop方法中循环执行从MessageQueue队列读取 Message对象,并把Message对象交由Handler处理,调用Handler的dispatchMessage方法。
3.Fragment 直译是:碎片
Fragment
extends Object
Know Direct Subclasses
DialogFragment, ListFragment,PrefrenceFragment ,WebViewFragment
Activity可以由多个Fragment组成,一个Fragment也可以添加到多个Activity.Fragment拥有自己的生命周期和接收,处理用户的事件。可以动态添加,替换和移除某个Fragment.
静态添加Fragment,步骤:1.定义自己的布局文件。2.继承Fragment类,实现和布局文件的关联。3.在使用的Activity的布局文件添加。
1. fragment.xml fragment的layout文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@color/colorBlack"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@mipmap/ic_launcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/fragment_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
2.定义继承Fragment类,唯一必须实现的方法onCreateView()方法中,的view要解析,和返回
public class TestFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG,"onCreateView");
View view=inflater.inflate(R.layout.fragment,container);
TextView textView= (TextView) view.findViewById(R.id.fragment_text);
textView.setText("极客班");
textView.setTextColor(Color.WHITE);
textView.setTextSize(20);
return view;
}
}
3.到activity的布局文件中调用
<!--id和name属性,要定义。
name是包名加fragment类名-->
<fragment
android:id="@+id/fragment_test"
android:name="com.exa.test3fragment.TestFragment"
android:layout_width="match_parent"
android:layout_height="200dp"/>
动态添加Fragment:
1.在activity使用FragmentTransaction管理Fragment(包括继承类和其布局文件)
新建MyFragment类继承Fragment ,
新建Fragment的布局文件R.layout.xxx. 类似于list_item中item的布局文件
在onCreateView()方法中,添加view.类似activity中的setContentView(int R.layout.xxx)
View view =inflater.inflate(R.layout.xxx,container,false);
return view;
2. 从context中获得FragmentManager
FragmentManager fragmentManager=getFragmentManager();
3. 从FragmentManager中获得FragmentTransaction
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
4. 在FragmentTransaction中处理事情,新建对象,进行添加,移除等处理.记得最后处理完,一定要commit();
MyFragment myFragment=new MyFragment();
fragmentTransaction.add(container,myFragment) 添加
fragmentTransaction.remove() 移除
fragmentTransaction.commit() 上交
5. find方法 通过ID,通过tag
Fragment fragment=fragmentManager.findFragmentById(R.id.xxx);
此方法的使用需要提前设置tag.在添加时,add()方法,最后添加一个参数,类似字符串。
fragmentTransaction.add(container,myFragment,“tag”) 添加
Fragment fragment=fragmentManager.findFragmentByTag(“tag”) 通过tag查找
1.新建,继承Fraagment类,和静态添加时不同,留意onCreateView()方法中,解析view,第三个参数设置false
public class TestFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG,"onCreateView");
/**
* 第三个参数设置,false.让这个frament可以实现复用
*/
View view=inflater.inflate(R.layout.fragment,container,false);
TextView textView= (TextView) view.findViewById(R.id.fragment_text);
textView.setText("极客班");
textView.setTextColor(Color.WHITE);
textView.setTextSize(20);
return view;
}
}
2.在activity的布局文件中,添加放置fragment的容器。在add方法时会调用该ID
<!--放置fragment的容器,放在activity的布局文件中-->
<LinearLayout
android:id="@+id/fragment_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
3.在要添加的Activity中操作
public class MainActivity extends AppCompatActivity {
private android.app.FragmentManager mFragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragmentManager=getFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
TestFragment testFragment=new TestFragment();
/**
* 添加Fragment
* 参数1,int containerViewId.就是一个布局的ID值
* 参数2,fragment ,对象
* 参数3,tag,findFragmentByTag使用
*/
fragmentTransaction.add(R.id.fragment_view,testFragment,"test_fragment_tag");
fragmentTransaction.remove(testFragment).commit();
/**
* fragmentManager来调用方法findFragmentById
* 就是container的id
*/
Fragment fragment=mFragmentManager.findFragmentById(R.id.fragment_view);
fragment=mFragmentManager.findFragmentByTag("test_fragment_tag");
// 进行判断,得到的fragment是不是TestFragment的实例
if(fragment instanceof TestFragment){
//TODO:DO your aciton
// 添加或移除
}
}
}
最后介绍下Fragment家族常用的API
Fragment常用的三个类:
android.app.Fragment, 主要用于定义Fragment
android.app.FragmentManagere, 主要用于在Activity中操作Fragment
android.app.FragmentTransaction, 保证一系列Fragment操作的原子性,事务代表的意义
获取FragmentManager getFragmentManager()
获取FragmentTransaction fm.beginTransaction() 开启一个事务
主要的方法都是:
transaction.add() 添加一个
transaction.remove()从Activity中移除一个Fragment,如果被移除的Fragment没有添加到 回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。
transaction.replace() 使用一个Fragment替换当前的,实际上就是remove()和add()的合体。
transaction.hide() 隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
transaction.show() 显示之前隐藏的Fragment
transaction.detach() 会将view从UI中移除
transaction.attach() ,重建视图
transaction.commit() 提交事务。必须执行的一个方法。
欢迎留言