ListView 的简单实现与优化并实现share动画Activity的跳转

来源:互联网 发布:手机淘宝开店在哪里 编辑:程序博客网 时间:2024/05/21 08:44

这篇文章主要是实现ListView的简单运用,即自定义ListView,在android 5.0之前ListView是应用最广泛的一个系统组件,

由于5.0后新的RecyclerView改良了ListView,所以5.0以后都开始应用RecyclerView,但是作为一个追求完美的程序猿,你必须具备这些技能,下面就让我们来看看ListView是实现,先来果

这就是整体效果图,下面我们来一一实现

先来看看ListView 中的布局

在activity_mian.xml布局中加一个ListView非常简单

<ListView    android:layout_width="match_parent"    android:layout_height="match_parent"    android:id="@+id/lv_item" />
但是如果只加这个控件的话是不能显示的  还必须定义一个Adapter适配器,就是用来适配数据显示在布局中的

这里我们用到的自定义布局list_item.xml用来显示ListView中每个Item的内容

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content">    <ImageView        android:layout_width="40dp"        android:layout_height="40dp"        android:id="@+id/iv_img"        android:src="@drawable/a"        android:transitionName="iv_ico"/>    <TextView        android:layout_width="match_parent"        android:layout_height="20dp"        android:text="11111111"        android:layout_alignParentTop="true"        android:layout_toEndOf="@+id/iv_img"        android:id="@+id/tv_name"        android:transitionName="tv_name"/>    <TextView        android:layout_width="match_parent"        android:layout_height="20dp"        android:text="1111111111"        android:layout_below="@+id/tv_name"        android:layout_toEndOf="@+id/iv_img"        android:id="@+id/tv_intro"        android:transitionName="tv_intro"/></RelativeLayout>
然后自定义一个Person类 ListView的每Item就用于显示Person的字段(属性)
public class Person implements Serializable{    private int icoId;    private String name;    private String intro;    public Person(int icoId,String name,String intro){        this.icoId=icoId;        this.name=name;        this.intro=intro;    }
这里为了篇幅get,set方法就自己用快捷方式生成吧
然后在写个自定义的Adapter用来适配listView数据
public class MyAdapter extends ArrayAdapter {    private int resourceId;    public MyAdapter(Context context, int textViewResourceId, List<Person> objects){        super(context,textViewResourceId,objects);        resourceId=textViewResourceId;    }    @NonNull    @Override    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {        Person person = (Person) getItem(position);        View view;        ViewHolder viewHolder;        if(convertView == null){            view = LayoutInflater.from(getContext()).inflate(R.layout.list_item,parent,false);            viewHolder = new ViewHolder();            viewHolder.personImage=(ImageView)view.findViewById(R.id.iv_img);            viewHolder.personName=(TextView)view.findViewById(R.id.tv_name);            viewHolder.personIntro=(TextView)view.findViewById(R.id.tv_intro);            view.setTag(viewHolder);//viewHolder储存在view        }else{            view=convertView;            viewHolder=(ViewHolder)view.getTag();//重新获取viewHolder        }        viewHolder.personImage.setImageResource(person.getIcoId());        viewHolder.personName.setText(person.getName());        viewHolder.personIntro.setText(person.getIntro());        return view;    }    class ViewHolder{        ImageView personImage;        TextView personName;        TextView personIntro;    }}
这里自定义的MyAdapter继承的ArrayAdapter,先看看android中的适配器的继承树

这里我们继承的ArrayAdapter,这个适配器我觉得很好用 一般情况也够用这里我们重写了它的getView方法,该方法就是

用来加载listview中每个item中的内容的由于ListView还有性能优化的问题,所以这里把ListView的优化问题一并写了

getView方法中的ViewconvertView参数就是将之前加载的布局缓存起来以便重用,所以我们解析布局之前做个判断

如果converView为null则解析加载布局,如果已经加载过了就直接用converView,然后因为在加载布局是要通过findViewById来加载每个控件的实例 ,所以写个内部类来优化这样一来加载每个Item就只用加载一次布局,也只会存在每个控件的一个实例,现在的ListView在快速滑动是的效率就大大提高了.写好了自定义的adapter然后就是为ListView设置适配器了在MainActivity中设置

protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    initPerson();    MyAdapter adapter = new MyAdapter(MainActivity.this, R.layout.list_item,persons);    ListView list = (ListView)findViewById(R.id.lv_item);    list.setAdapter(adapter);
这里由于是测试所以就写个initPerson()方法手动为ListView初始化数据了

private void initPerson() {    for(int i=0;i<3;i++){        Person person1 = new Person(R.drawable.a,"android","android开发者");        persons.add(person1);        Person person2 = new Person(R.drawable.b,"WEB","WEB开发者");        persons.add(person2);        Person person3 = new Person(R.drawable.c,"嵌入式","android开发者");        persons.add(person3);        Person person4 = new Person(R.drawable.d,"JAVA","android开发者");        persons.add(person4);        Person person5 = new Person(R.drawable.e,"C#","C#开发者");        persons.add(person5);        Person person6 = new Person(R.drawable.f,"前端","前端开发者");        persons.add(person6);        Person person7 = new Person(R.drawable.g,"IOS","IOS开发者");        persons.add(person7);    }}
这样就是实现了自定义ListView的显示,但是ListView光显示是不够的,还要能有点击事件了

listView有自己的OnItemClickListener接口,实现点击事件很简单

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {    @Override    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {        Intent intent = new Intent(MainActivity.this, BActivity.class);        Person person = persons.get(position);        int icoId=person.getIcoId();        Bundle bundle = new Bundle();        bundle.putSerializable("person",person);        intent.putExtras(bundle);        View ico = findViewById(R.id.iv_img);        View name =findViewById(R.id.tv_name);        View intro=findViewById(R.id.tv_intro);        startActivity(intent, ActivityOptions.makeSceneTransitionAnimation((Activity) view.getContext(),                Pair.create(ico,"iv_ico"),                Pair.create(name,"tv_name"),                Pair.create(intro,"tv_intro")).toBundle());    }});
这里面的代码是实现share动画跳转Activity的代码,可能有的人看不懂,没关系,里面的代码可以忽略

直接用Toast测试

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {    @Override    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {        Toast.makeText(MainActivity.this,"on click"+position+"",Toast.LENGTH_SHORT).show();});
如果想看share动画的可以看看上一篇文章

Android 动画Activity转场动画入门

下一篇就写自定义的RecyclerView   由于RecyclerView的实现比ListView要复杂的多所以有必要做对比