ListView在Activity和Fragment中的显示和使用

一:在Fragment中显示ListView

1.在Fragment中显示ListView,主要用到ListFragment这个类,新建一个类继承ListFragment,ListFragment内置了ListView,所以无需覆盖Fragment的onCreateView()方法或者为Fragment生成一个带有ListView的布局,ListFragment默认实现 一个全屏ListView布局;

2.把Fragment托管到Activity中;

<span style="font-size:14px;">public abstract class SingleFragmentActivity extends FragmentActivity {
	
	protected abstract Fragment createFragment();
	
	 @Override
	    protected void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        setContentView(R.layout.activity_fragment);
	        
	        FragmentManager manager = getFragmentManager();
	        Fragment fragment = manager.findFragmentById(R.id.fragmentContainer);
	        
	        if(fragment == null) {
	        	fragment = createFragment();
	        	manager.beginTransaction()
	        	     .add(R.id.fragmentContainer, fragment)
	        	     .commit();
	        }
	        
	    }</span>

}

在这里有一个比较好的技巧,因为在Activity中托管Fragment基本都是开启事务添加添加FragmentContainer和Fragment实例,这样几乎每一个创建的Activity托管Fragment都要用到同一套代码,要是托管多少个Fragment就在多少个Activity中编写同一套代码,会显得很傻,因此可以通过创建一个抽象类,并提供一个抽象方法用于创建Fragment的实例。然后让每一个需要托管Fragment的Activity都继承这个抽象类,并实现父类的抽象方法就可以了

3.有了ListView之后,接下来就是创建适配器,也就是ArrayAdapter<T>实例,把ListView和数据集串联起来,这一步在Fragment和Activity中都几乎相同。

4.最后可以使用setListAdapter(ListAdapter)为ListFragment管理的内置ListView设置Adapter。

public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		getActivity().setTitle(R.string.crime_title);
		crimes = CrimeLab.get(getActivity()).getCrimes();
		
		CrimeAdapter adapter = new CrimeAdapter(getActivity(), android.R.layout.simple_list_item_1, crimes);
		setListAdapter(adapter);
	}

要注意的是,其中的getActivity()是ListFragment的便利方法,表示返回托管的Activity,这样就可以在fragment中处理activity的相关事务,其实ListFragment中还有类似的便利方法,getListAdapter()表示返回设置在ListFragment列表视图的adapter,setListAdapter()表示为ListFragment管理的内置ListView设置Adapter。


当你想优化这个ListView,有下面这些方面可以优化:

1.为每一个item设置点击事件

这通过覆盖ListFragment的onListItemClick(ListView l, View v, int position, long id)实现

@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		//getListAdapter()返回设置在ListFragment的adapter
		Crime c = ((CrimeAdapter)getListAdapter()).getItem(position);
		Intent intent = new Intent(getActivity(), CrimeActivity.class);
		intent.putExtra(CrimeFragment.EXTRA_CRIME_ID, c.getId());
		startActivity(intent);
		
	}
2.定制列表项

首先创建一个你理想中列表项布局,然后新建类继承ArrayAdapter<T>,覆盖getView(int position, View converView, ViewGroup parent)

private class CrimeAdapter extends ArrayAdapter<Crime>{
		
		SimpleDateFormat fm = new SimpleDateFormat("E,M月d日,yyyy");
		ViewHolder viewHolder;
		//调用
		public CrimeAdapter(ArrayList<Crime> crimes){
			super(getActivity(), 0, crimes);
		}

		
		public View getView(int position, View convertView, ViewGroup parent) {
			
			if(convertView == null){
				convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_crime, 
						null);
				viewHolder = new ViewHolder();
				viewHolder.titleTextView = (TextView) convertView.
						findViewById(R.id.crime_list_item_titleTextView);
				viewHolder.dateTextView = (TextView) convertView.
						findViewById(R.id.crime_list_item_dateTextView);
				viewHolder.solvedCheckBox = (CheckBox) convertView.
						findViewById(R.id.crime_list_item_solvedCheckBox);
				convertView.setTag(viewHolder);
				
			}
			
			Crime c = getItem(position);
			
			viewHolder = (ViewHolder) convertView.getTag();
			viewHolder.titleTextView.setText(c.getTitle());
			
			viewHolder.dateTextView.setText(fm.format(c.getDate()));
			
			viewHolder.solvedCheckBox.setChecked(c.isSolved());
			
			return convertView;
			

		}
		
		private class ViewHolder{
			TextView titleTextView;
			TextView dateTextView;
			CheckBox solvedCheckBox;
		}
		
		
	}

3.虽然我们在代码中用if语句来判定是否存在了布局,这样避免了每次都要产生一次新布局,但是listView的控件仍然每一次加载布局时都会重新实例化一遍控件。因此,在上述代码中了,我们新建一个内部类ViewHolder,在ArrayAdapter的子类中创建ViewHolder实例,把控件的实例都放在viewHolder的实例中,然后调用view的setTag()方法把viewHolder对象储存到View中。当converView不为空时调用View的getTag()把viewHolder取出来。


二:在Activity中显示ListView

因为Activity没有内置ListView,所以需要在activity布局中添加ListView控件,并在Activity中获得ListView实例,接下来也是跟Fragment的第三步一样,创建适配器把listView和数据集连接起来,只不过最后Fragment中用的是setListAdapter(ListAdapter),而Activity需要用ListView实例去调用setAdapter(ListAdapter)。接下来的优化Fragment和Activity几乎都差不多,这里便不再多说。


最后还有一点值得思考

View convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_crime, null);
View converView = LayoutInflater.from(getContext().inflate(R.layout.list_item_ctime,null));

这两种产生布局的方法有什么不同?



  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值