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

来源:互联网 发布:qq一手数据出售群 编辑:程序博客网 时间:2024/06/10 22:43

一:在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)实现

@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {//getListAdapter()返回设置在ListFragment的adapterCrime 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));

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



1 1
原创粉丝点击