学习到fragment UI Fragment管理器
创建一个Fragment的xml界面,再在java代码中,实现fragment的生命周期:
public class CrimeFragment extends Fragment{
private Crime mCrime;
private EditText mTitleFieId;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mCrime=new Crime();
}
创建和配置Fragment试图是在这一个fragment生命周期方法完成的:
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
该方法为实例化Fragment视图的布局,然后将实例化的View返回给托管的acrivity。
LayoutInflater及ViewGroup是实例化布局的必要参数,Bundle用来存储恢复数据
在onCreateView(...)方法中:fragment的试图使直接通过调用LayoutInflater,inflate(...)方法并传入布局的资源ID生成的。
第二个参数是视图的父视图,需要父视图来正确配置组件。
第三个参数告知布局生成器是否将生成的试图添加给父视图。
fragment中监听器方法的设置和activity中完全一样。创建实现TextWatcher监听器接口的匿名内部类
TextWatcher有三种方法,现在只需要关注其中的onTextChanged(..)方法。在其方法中,调用CharSequence(代表用户输入)的toString方法
该方法用来最后返回用来设置Crime标题的字符串。
mTitleFieId.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s,int start,int before,int count){
mCrime.setmTitle(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
fragment事务被用来添加、移除、附加、分离或替换fragment队列中的fragment。
是使用fragment在运行时组装和重装用户界面的关键。FragmentManager管理着fragment事务回退栈。
android:layout_weight 属性的工作原理:
告知LinearLayout如何布置安排子组件,虽然给组件设置了同样的值后,但却不意味着它们在屏幕上占据同样的宽度。在决定子组件视图的宽度时,线性
布局使用的是layout_width和layout_weight参数的混合值
2016/11/28
图书馆: 第九章 使用RecyclerView显示列表
单例是特殊的java类,在创建单例时,一个单例类仅允许创建一个实例,
Android从内存里移除应用时,单例对象也就不复存在了
List<E>是一个支持存放指定数据类型对象的java有序数组类,它具有获取,新增和删除数组中元素的方法。
常见的List实现是1.ArrayList LinkedList、Voctor
Android 在声明变量的时候,建议使用list接口类型
ArrayList 和LinkedList和Voctor的区别:
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized).
因此,开销就比ArrayList要大.正常情况下,大多数的Java程序员使用ArrayList而不是Vector,
因为同步完全可以由程序员自己来控制。
RecyclerView、Adapter、ViewHolder
RecyclerView是ViewGoup的子类,每一个视图为一个View对象,RecyclerView自身不会创建视图,创建的是一个ViewHodler,而ViewHolder
引用着一个个ItemView
Adapter是一个控制器对象
作用:
1.创建必要的ViewHodler 2.绑定ViewHoder至模型层数据
ViewHolder的作用:
是一个持有者的类,里面没有方法,只有属性,作用为一个零售的存储器,把getView方法
中每次返回的View存起来,能够下次再用,优点:不必每次都到布局文件中去拿View,提高了效率
Fragment Argument:
fragment有两种方法获取intent中的数据,一种简单直接,另一种为fragment argument
fragment argument:
每个fragment实例都可附带一个Bundle对象。该bundle包含有键值对,我们可以像附加extra到Activity的intent中那样使用它们。一个键值对即一个argument
创建Fragment argument,首先需要创建bundle对象,然后使用Bundle中的"put"方法,将argument添加到bundle中
附加argument 给fragment:
附加fragment bundle给fragment,需要调用Fragment.SetArgument(Bundle)方法,必须在创建在Fragment之后,添加给Activity前完成:
1.添加名字为newInstance()的静态方法,而且为满足fragment创建argument,activity可以传入任何需要的参数给newInstanc()方法
public static CrimeFragment newInstance(UUID crimeId){ Bundle args=new Bundle(); args.putSerializable(ARG_CRIME_ID,crimeId); CrimeFragment fragment=new CrimeFragment(); fragment.setArguments(args); return fragment;
ViewPager:
ViewPager与PagerAdapter间的配合, PagerAdapter的子类FragmentStatePagerAdapter提供了两个方法:
getCount()和getItem(int)
FragmentStatePagerAdapter与FragmentPagerAdapter :
FragmentPagerAdapter是另外一种可用的PagerAdapter 其用法与FragmentStatePagerAdapter方法基本一致 不同在于:
卸载不需要的Fragment时,各自采用的处理方法不同:
FragmentStatePagerAdapter会销毁不需要的Fragment,事务提交之后,fragmentManager中的fragment会被彻底移除
FragmentStatePagerAdaoter类中的state表明:在销毁fragment时,可在onSaveInstanceState(Bundle)方法中保存fragment的Bundle信息
切换回来时,保存的实例状态可用来恢复成新的fragment
FragementPagerAdapter:
在销毁不需要的fragment时, fragment会调用事务的detach(Fragment)方法来处理,而非remove(Fragment)方法,
FragmentPagerAdapter只是销毁了fragment的视图,fragment实例还保留在fragmentManager中
所以FragmentPagerAdapter创建的fragment永远不会被销毁
ViewPager的工作原理:
PagerAdapter要比Adapter,因为要处理更多的视图管理工作,
PagerAdapter不使用可返回的onBindViewHolder(...)方法:
1.public object instantiateItem(ViewGroup container,int position):告诉pager adapter创建指定位置的列表项视图,然后将其添加给ViewGroup视图容器
2.public void destroyItem(ViewGroup container,int position,Object object): 告知pager adapter销毁已建视图
3.piblic abstract boolean isViewFromObject(View view,Object object)
instantiateItem(ViewGroup ,position)方法不是立即创建Fragment,PagerAdapter可自行决定何时创建视图
会调用isViewFromObject(View,Object)方法 Object为返回的对象
public boolean isViewFromObject(View view,Object object){
return ((Fragment)object).getView()==view;
}
对话框
Android 中有三种可以用于对话框的按钮:
positive按钮、 negative按钮、neutral按钮 当用户点击position按钮的时候,接受对话框展现消息,如果同一个对话框上放置有多个按钮,按钮的类型
与命名决定着它们在对话框上显示的位置
要将DialogFragment添加到FragmentManager管理并放置到屏幕上,可调用fragment实例:
public void show(FragmentManager manager,String tag)
public void show(FragmentTransaction transaction,String tag)
当创建的Fragment被销毁和重建后,操作系统也会关联它们,调用一下Fragment方法可创建这种关联:
public void setTargetFragment(Fragment fragment,int requestCode):
该方法有两个参数:目标fragment以及类似于传入startActivityForResult(...)方法的请求代码。需要时,目标fragment使用请求代码确认是哪个fragment在回收数据
Activity.OnActivityResult(..)方法是ActivityManager在子activity销毁后调用的父activity方法,处理activity间的数据返回时,会自动调用Activity
.OnActivityResult(...)方法
1.编写需要用户大量输入、以及要求更多空间显示输入的应用,并且要让应用同事支持手机和平板设备时,使用OnActivityResult(...)方法返回数据给目标
fragment是比较方便的
2.手机屏幕空间有限,因此通常需要使用activity托管全屏的fragment界面,来显示用户输入要求,该子activity会由父activity的fragment以调用startActivityForResult(..)方法的
方式启动。子activity被销毁后,父activity会接受到onActivityResult(...)方法的调用请求,并将之转发给启动子activity的fragment
使用AppCompat库
完全整合AppCompat库:
1.添加AppCompat依赖项
2.使用一种AppCompat主题
3.确保所有的activity都是AppCompatActivity子类
4.让activity类继承AppCompatActivity类
主题设置:1.Theme.AppCompat:黑色主题 2.Theme.AppCompat.Light:浅色主题 3.Theme.AppComPat.DarkActionBar: 带黑色工具栏的浅色主题
Fragment.onCreateOptionMenu(Menu,MenuInflater)方法是由FragmentManager负责调用的。当activity接收操作系统的onCreateOptionMenu(..)方法回调请求时,我们需要告知fragment
其管理的fragment应接收onCreateOptionsMenu(...)方法的调用指令,需调用以下方法:
public void setHasOptionsMenu(boolean hasMenu)
点点击菜单中的菜单项时,fragment会接收到onOptionsItemSelected(MenuItem)方法的回调请求。传入该方法的参数是一个描述用户选择的MenuItem实例
public boolean onOptionsItemSelected(MenuItem item){ switch(item.getItemId()){ case R.id.menu_item_new_crime: Crime crime=new Crime(); CrimeLab.get(getActivity()).addCrime(crime); Intent intent=CrimePagerActivity.newIntent(getActivity(),crime.getmId()); startActivity(intent); return true; case R.id.menu_item_show_subtitle: mSubtitleVisible=!mSubtitleVisible; getActivity().invalidateOptionsMenu(); updateSubtitle(); return true; //如果菜单项ID不存在,超类版本方法会被调用 default: return super.onOptionsItemSelected(item); } }
菜单通常包含多个菜单项,通过检查菜单项ID,可确定被选定的是哪个菜单项,然后做出相应的响应,此ID通常是菜单定义文件中赋予菜单项资源的资源ID
MenuItem subtitleItem=menu.findItem(R.id.menu_item_show_subtitle); if (mSubtitleVisible){ subtitleItem.setTitle(R.string.hide_subtitle); }else { subtitleItem.setTitle(R.string.show_subtitle); }
Android中遇见层级导航带来的问题:导航回退到的目标activity会被完全重建,既然父activity是全新activity,实例变量值以及保存的实例状态显示会
彻底丢失
在向上导航时保证子标题的可见状态有两种办法:
if (savedInstanceState!=null){ mSubtitleVisible=savedInstanceState.getBoolean(SAVED_SUBTITLE_VISIBLE); }
public void onSaveInstanceState(Bundle outState){ super.onSaveInstanceState(outState); outState.putBoolean(SAVED_SUBTITLE_VISIBLE,mSubtitleVisible); }
1.覆盖向上导航的机制:在CrimePagerActivity的finish方法直接退到一个activity界面,但这只能退回一个层级。但实际开发的时候应用里需要多层级导航
2.启动CrimePagerActivity时,把子标题的状态作为extra信息传给它,在CrimePagerActivity中覆盖getParentActivityIntent()方法,用附加extra
信息的intent重建CrimeListActivity