android权威编程指南学习笔记

activity中的代码基本都转移到Fragment里了 这样真的好么

1. 首先创建模型类,根据需要添加数据集中存储池来存储模型对象

(如使用支持存放指定数据类型对象的Java有序数组类,ArrayList, 具有获取、新增、删除数组中元素的方法。)

public class DemosLab {
	//有序组成员变量
	private ArrayList mDemos;//静态对象
	private static DemosLab sDemosLab;
	private Context mAppContext;
	private DemosLab(Context appContext){
		mAppContext = appContext;
		mDemos = new ArrayList();
		
		Demo demo = new Demo();
		demo.setName("Service");
		demo.setDate("2015/9/9"); 
		demo.setDescription("学习Service");
		demo.setFinished(false);
		mDemos.add(demo);
	}
	public ArrayList getDemos(){
		return mDemos;
	}
	public Demo getDemo(String name){
		for(Demo demo : mDemos){
			if(demo.getName().equals(name))
			  return demo;
		}
		return null;
	}
	public static DemosLab get(Context c){
		if(sDemosLab == null){
			sDemosLab = new DemosLab(c.getApplicationContext());
		}
		return sDemosLab;
	}
    }


2.继承抽象自定义Activity

  目前仅新增了添加Fragment方法,activity布局名默认为 activity_main
public abstract class SingleFragmentActivity extends FragmentActivity
//抽象方法 提供Fragment实例
protected abstract android.app.Fragment createFragment();
@Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
        
      if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
            //抽象方法 也就是模板,具体实现具体对待
                    .add(R.id.container,createFragment())
                    .commit();
        }
   }
  }




3.继承抽象自定义Fragment(继承ListFragment)
新增添加Fragment参数的方法、选项菜单(监听)

public class DemosListFragment extends ListFragment {
	private static final int REQUESR_DEMOSLIST = 1;
	private ArrayList mDemos;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getActivity().setTitle(R.string.app_name);
//此项根据需要设置是否保留Fragment
      setRetainInstance(true);
		//设置此项才可以在fragment中正确使用选项菜单
		setHasOptionsMenu(true);
		//使用DemosLab的静态方法获取其实例进而获得demos数组
		mDemos = DemosLab.get(getActivity()).getDemos();
		//使用自定义Adapter填充数据
		DemoAdapter adapter = new DemoAdapter(mDemos);
		setListAdapter(adapter);
	}
	//状态保存
	@Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);

//选项菜单
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		// TODO Auto-generated method stub
		super.onCreateOptionsMenu(menu, inflater);
		inflater.inflate(R.menu.main, menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if(item.getItemId() == android.R.id.home){
			Toast.makeText(getActivity(), "返回"+item.getItemId(),Toast.LENGTH_SHORT).show();
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			NavUtils.navigateUpFromSameTask(getActivity());
		}
		Toast.makeText(getActivity(), ""+item.getItemId(),Toast.LENGTH_SHORT).show();
		// 返回true表明已完成处理
		return true;
	}
//覆盖Fragment.onActivityForResult方法从被启动activiy获取结果
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if(requestCode == REQUESR_DEMOSLIST){
			Toast.makeText(getActivity(), "got result:"+resultCode, Toast.LENGTH_SHORT).show();
		}
	}
//刷新列表项
	@Override
	public void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		((DemoAdapter)getListAdapter()).notifyDataSetChanged();
	}
//Toast便捷方法
protected void toast(Context context,String text) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
//警告对话框便捷方法
protected void alert(String content) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()).setTitle("提示").setMessage(content);
builder.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mtoast(getActivity(), ""+which);
}
);
builder.create().show();
}




4.自定义Adapter
private class DemoAdapter extends ArrayAdapter{

		public DemoAdapter(ArrayList demos) {
			super(getActivity(),0,demos);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
//列表优化,convertView是刚刚被销毁的视图
			if(convertView == null){
				convertView = getActivity().getLayoutInflater()
						.inflate(R.layout.list_item_demo, null);
			}
			Demo demo = getItem(position);
			TextView tv1 = (TextView) convertView.findViewById(R.id.textView1);
			TextView tv2 = (TextView) convertView.findViewById(R.id.textView2);
			CheckBox finishedBox = (CheckBox) convertView.findViewById(R.id.checkBox1);;
			tv1.setText(demo.getName()+"\n"+demo.getDescription());
			tv2.setText(demo.getDate());
			finishedBox.setChecked(demo.isFinished());
			return convertView;
		}
	}




//常用功能
1.使用dialog
//TODO
2.Fragment/Activity间传递数据
 // Activity.onActivityForResult 在子Activity销毁后由ActivityManager自动调用的父类方法 随后FragmenManager会调用对应Fragment.onActivityResult
而下面两个Fragment间传递数据则要自己调用Fragment.onActivityResult()方法
activity间:   Activity.startActivityForResult &  Activity.onActivityForResult ------Activity.setResult(int resultcode)
//从Fragment中启动Activity,使用Fragment.startActivityForResult()
基于fragment的activity间:目标activity接受父activity的数据后调用托管Fragment的newInstance静态方法 其中有Fragment..setArguments(Bundle)  -------  getArguments()
Activity.setResult(int resultcode)
//与Activity间的关联的区别:
对于activity间的回传,我们调用startActivityForResult()方法,ActivityManager负责跟踪记录父子Activity见得关系,当子Activity返回数据被销毁之后,ActivityManager知道应该把数据返回给谁。
      //而此处我们需要为要返回数据的Fragment指定目标Fragment
FragmentManager可使用该请求码得知是哪一个在返回数据
一般此项在目标Fragment中进行设置。。。。。。。。。。
同一Activity托管的Fragment间: 在Fragment中调用目标Fragment的newInstance方法传去参数(同上),-------  XFragment.setTargetFragment(TFragment .this, RequestCode)
fragment.getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);
android权威编程指南学习笔记_第1张图片
3.fragment的保留
设置fragment的属性值---->在onCreate方法中调用setRetainInstance(true);其默认值是false;
表明其不会被保留。所以当设备旋转时fragment会随托管activity一起被销毁并重建,设为true则会被一直保留并在需要时原封不动的传递给新的activity。(实际情况是:销毁和重建fragment视图,但保留fragment自身)。
//TODO fragment生命周期图
保留fragment只能应对短时间的像设备旋转这样的销毁,若长久离开进程关闭时,activity、fragment(无论保留与否)都会消亡,而activity记录不会,因此应该覆盖Fragment.onSaveInstanceState();
4.操作栏
1)选项菜单(在Fragment中创建 同在Activity)
a.定义选项菜单的XML文件 res/menu       id,icon,title,showAsAction(ifRoom|withText|always|never)
b.setHasOptionsMenu(true) 通知FragmentManager应该接受Activity的方法调用指令
c.重写
@Override
		public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
			// TODO Auto-generated method stub
			super.onCreateOptionsMenu(menu, inflater);
			inflater.inflate(R.menu.main, menu);
		}
		
		@Override
		public boolean onOptionsItemSelected(MenuItem item) {
			if(item.getItemId() == android.R.id.home){
				Toast.makeText(getActivity(), "返回"+item.getItemId(),Toast.LENGTH_SHORT).show();

				NavUtils.navigateUpFromSameTask(getActivity());
			}
			Toast.makeText(getActivity(), ""+item.getItemId(),Toast.LENGTH_SHORT).show();
			// 返回true表明已完成处理
			return true;
		}
2)层级式导航(Ancestral navigation)
使操作栏上的应用图标具有向上按钮的功能。
a.调用setDisplayHomeAsUpEnable(true)设置Fragment属性
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
			if(NavUtils.getParentActivityName(getActivity())!=null){
				getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
			}
		}
b.在AndroidManifest.xml中为各个子Activity添加新的meta-data属性,指定其父类
eg.



c.监听(相当于一个选项菜单项,在选项菜单监听器中增加一项判断即可)
@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if(item.getItemId() == android.R.id.home){
if(NavUtils.getParentActivityName(getActivity())!=null){
NavUtils.navigateUpFromSameTask(getActivity());}// 返回true表明已完成处理return true;}




5.上下文菜单与上下文操作模式
1)浮动上下文:(注册在ListView)
首先在onCreateView方法中向组件注册上下文菜单
Fragment. registerForContextMenu(listView);
@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		getActivity().getMenuInflater().inflate(R.menu.demo_list_item_context, menu);
	}
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		int position = info.position;
		DemoAdapter adapter = (DemoAdapter) getListAdapter();
		Demo demo = adapter.getItem(position);
		switch (item.getItemId()) {
		case R.id.delete:
			break;
		case R.id.cancle:
			break;
		default:
			break;
		}
		return true;
	}

2)上下文操作模式:(ListView多选模式)
1.向ListView注册:listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
2.实现AbsListView.MultiChoiceModeListener 接口的监听器
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {...}
包含以下回调方法,视图在选中或撤销选中时会触发它
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// TODO Auto-generated method stub
}
MultiChoiceModeListener实现了另一个接口,即ActionMode.Callback,必须实现以下四个方法。
				public boolean onPrepareActionMode(ActionMode mode, Menu menu) {}
				public void onDestroyActionMode(ActionMode mode) {}
				public boolean onCreateActionMode(ActionMode arg0, Menu arg1) {}
				public boolean onActionItemClicked(ActionMode arg0, MenuItem arg1) {}

在Fragment的onCreateView方法中注册:
		if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
			registerForContextMenu(listView);							//这是注册浮动上下文菜单(无需手动绑定监听器)
		else {
			listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);				//这是注册多选上下文操作模式
			listView.setMultiChoiceModeListener(new MultiChoiceModeListener(){实现上面的五个方法}
主要是这两个方法:
@Override			
				public boolean onCreateActionMode(ActionMode arg0, Menu arg1) {
					MenuInflater inflater = arg0.getMenuInflater();
					inflater.inflate(R.menu.demo_list_item_context, arg1);
					return true;
				}
				
				@Override
				public boolean onActionItemClicked(ActionMode arg0, MenuItem arg1) {
					
					switch (arg1.getItemId()) {
					case R.id.delete:
						new AlertDialog.Builder(getActivity()).setMessage("deleted!").setPositiveButton("确定", null).create().show();
						break;
					case R.id.cancle:
						new AlertDialog.Builder(getActivity()).setMessage("cancled!").setPositiveButton("确定", null).create().show();
						break;
					default:
						break;
					}
					return true;
				}
				
改变已激活视图的显示背景:
使用state list drawable
在drawable目录下创建以selector为根元素的xml文件:


    

设置列表项背景引用该资源:
android:background="@drawable/bgc_act"

····················································································································

其他视图上的上下文操作模式:

步骤如下---
1.设置一个实现View.OnLongClickListener接口的监听器

2.在监听器实现体内调用Activity.startActionMode(...)方法创建一个ActionMode实例  .实现AbsListView.MultiChoiceModeListener 接口的监听器ActionMode实例是自动创建的
·
3.创建一个实现ActionMode.Callback接口的匿名实现作为参数传入startActionMode
eg:
TextView tv = (TextView) view.findViewById(R.id.text1);
		tv.setOnLongClickListener(new OnLongClickListener() {
			
			@Override
			public boolean onLongClick(View v) {
				getActivity().startActionMode(new ActionMode.Callback() {
					
					@Override
					public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
						// TODO Auto-generated method stub
						return false;
					}
					
					@Override
					public void onDestroyActionMode(ActionMode mode) {
						// TODO Auto-generated method stub
						
					}
					
					@Override
					public boolean onCreateActionMode(ActionMode mode, Menu menu) {
						mode.getMenuInflater().inflate(R.menu.demo_list_item_context, menu);
						return true;
					}
					
					@Override
					public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
						Toast.makeText(getActivity(), "ok", Toast.LENGTH_SHORT).show();
						return true;
					}
				});
				return false;
			}
		});


6.存储与加载本地文件













你可能感兴趣的:(android权威编程指南学习笔记)