安卓 列表listview

来源:互联网 发布:js继承 阮一峰 编辑:程序博客网 时间:2024/06/09 16:14

          当内容超过屏幕大小的时候,我们需要让屏幕容纳足够的展示,所以我们引入了一个控件,可滑动的控件,当然这里可以使用scorlview,scorlview里面只有有一个孩子,只能放一个布局,不过现在介绍一种专用的列表展示的view,listview。下面看如何使用

1.listview在xml中设置非常简单,只需设置一下宽和高。只有一个listview

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <TextView        android:id="@+id/Retorytext4"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="" />    <ListView        android:id="@+id/listview"        android:layout_width="match_parent"        android:layout_height="match_parent" />   </LinearLayout>
          二.下面介绍listview的适配器,一共有四种:1.Arrayadpter,单一的适配器,里面只能放String 。2.Simpleadapter,里面放图和字,要求数据是map集合,不方便 。3.Cursor适配器,适用展示数据库的数据。4.自定义适配器,继承baseadpter,数据源是任意对象,或者任意集合,展示任意布局,今天要使用的就是自定义适配器。

三、自定义适配器

1.首先写一个adapter继承Baseadapter有四个方法,第一个方法是这个代表集合的展示条目的长度

@Override    public int getCount()    {        return list.size();    }

2.第二个方法getItem().不会影响展示,一般用于activty获取适配器的某条数据,一般返回list.get(i)

 @Override    public Object getItem(int position) {        return null;    }
3.第三个方法也不用数据展示,用于Acitvty获取数据库数据的标号
 @Override    public long getItemId(int position) {        return 0;    }

4.第四个方法最为重要getView,代码也最多,1.代表你要展示的每一条view。2.返回一个view,否则无法展示

      3.必须的操作将数据添加到view布局所包含的控件中,这个方法是将数据和布局进行绑定的方法。

public View getView(int position, View view, ViewGroup parent) {    viewHolder viewHolder;    manager= Playmanager.getinstance();    final int Position=position;    if(view==null)    {        view=inflater.inflate(R.layout.listitem,null);        viewHolder=new viewHolder();        viewHolder.tv1=view.findViewById(R.id.textView4song);        viewHolder.tv2=view.findViewById(R.id.textViewname);        viewHolder.imag=view.findViewById(R.id.imageView5);        view.setTag(viewHolder);    }    else        {            viewHolder= (ListAdapter.viewHolder) view.getTag();        }   final Button btstart= view.findViewById(R.id.start);    viewHolder.tv1.setText(list.get(position).getSongname());    viewHolder. tv2.setText(list.get(position).getSingername());    Picasso.with(context)            .load(list.get(position).getAlbumpic_small())            .error(R.mipmap.ic_launcher)            .placeholder(R.drawable.dibu8)            .into(viewHolder.imag);    view.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {           list.get(Position).getUrl();            Log.e("msg","list.get(Position).getUrl()"+list.get(Position).getUrl());             manager.cutmusic(list.get(Position).getUrl());            if ( onclick != null) {                onclick.click(1);            }            Log.e("msg","onclick"+onclick);        }    });    return view;}






package com.wj.administrator.mcz.Adapter;import android.content.Context;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;import com.squareup.picasso.Picasso;import com.wj.administrator.mcz.JavaBean.josntop;import com.wj.administrator.mcz.R;import com.wj.administrator.mcz.util.Playmanager;import java.util.ArrayList;import static com.wj.administrator.mcz.R.id.imageView;/** * Created by Administrator on 2017/11/1 0001. */public class ListAdapter extends BaseAdapter{    private ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean> list;    private LayoutInflater inflater;    private Context context;    private Playmanager manager;    private Button button;    public ListAdapter(Button button)    {           this.button=button;    }    public  ListAdapter(ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean> list, Context context)    {             this.list=list;            this.context=context;            inflater=LayoutInflater.from(context);    }    @Override    public int getCount()    {        return list.size();    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }   class viewHolder   {       TextView tv1, tv2;       ImageView imag;   }    @Override    public View getView(int position, View view, ViewGroup parent) {        viewHolder viewHolder;        manager= Playmanager.getinstance();        final int Position=position;        if(view==null)        {            view=inflater.inflate(R.layout.listitem,null);            viewHolder=new viewHolder();            viewHolder.tv1=view.findViewById(R.id.textView4song);            viewHolder.tv2=view.findViewById(R.id.textViewname);            viewHolder.imag=view.findViewById(R.id.imageView5);            view.setTag(viewHolder);        }        else            {                viewHolder= (ListAdapter.viewHolder) view.getTag();            }       final Button btstart= view.findViewById(R.id.start);        viewHolder.tv1.setText(list.get(position).getSongname());        viewHolder. tv2.setText(list.get(position).getSingername());        Picasso.with(context)                .load(list.get(position).getAlbumpic_small())                .error(R.mipmap.ic_launcher)                .placeholder(R.drawable.dibu8)                .into(viewHolder.imag);        view.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {               list.get(Position).getUrl();                Log.e("msg","list.get(Position).getUrl()"+list.get(Position).getUrl());                 manager.cutmusic(list.get(Position).getUrl());                if ( onclick != null) {                    onclick.click(1);                }                Log.e("msg","onclick"+onclick);            }        });        return view;    }    private Onclick onclick;    public void setonlist(Onclick listener)    {        Log.d("TAG","setmItemOnClickListener...");        this.onclick = listener;    }   public interface Onclick    {        public void click(int v);    }}


4.准备数据,网上下载,list集合,子布局呢哪里来?子布局如何写呢,我们写了个listitem,就是这个xml,就是我们的模板。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    xmlns:card_view="http://schemas.android.com/tools"    android:weightSum="10"    android:layout_marginLeft="10dp"    >    <!--<android.support.v7.widget.CardView-->        <!--android:id="@+id/cardview"-->        <!--android:layout_width="match_parent"-->        <!--android:layout_height="wrap_content"-->        <!--android:layout_margin="14dp"-->        <!--card_view:cardBackgroundColor="@color/colorAccent"-->        <!--card_view:cardCornerRadius="10dp"-->        <!--card_view:cardElevation="5dp"-->        <!--android:foreground="?attr/selectableItemBackground"-->        <!--card_view:contentPadding="8dp">-->        <!--子布局控件-->        <!--<LinearLayout-->            <!--android:layout_width="300dp"-->            <!--android:layout_height="65dp"-->            <!--android:orientation="horizontal">-->    <ImageView        android:layout_width="0dp"        android:layout_height="65dp"        android:layout_weight="2"        app:srcCompat="@mipmap/ic_launcher_round"        android:id="@+id/imageView5" />    <LinearLayout        android:layout_width="0dp"        android:layout_height="65dp"        android:orientation="vertical"        android:layout_weight="6">        <TextView            android:layout_width="match_parent"            android:layout_height="0dp"            android:layout_weight="1"           android:gravity="bottom"            android:paddingBottom="5dp"            android:text="西湖水辅导辅导"            android:id="@+id/textView4song"            android:layout_alignParentTop="true"            android:layout_toRightOf="@+id/imageView5"            android:layout_toEndOf="@+id/imageView5" />    <TextView        android:id="@+id/textViewname"        android:layout_width="match_parent"        android:layout_height="0dp"        android:text="冰雨"        android:paddingTop="5dp"        android:layout_weight="1"       />        <ImageView            android:layout_width="320dp"            android:layout_height="1dp"            android:background="#ffffff"            android:paddingTop="10dp"            android:layout_below="@+id/textViewname" />    </LinearLayout><ImageViewandroid:layout_marginTop="10dp"android:id="@+id/imageView9"android:layout_width="0dp"android:layout_height="40dp"android:layout_marginLeft="30dp"android:layout_weight="1"android:src="@drawable/xiaosan333"    />    <!--</android.support.v7.widget.CardView>--></LinearLayout>

五如何传入数据呢和子布局到这个适配器里面,数据和子布局都是activty提供?

1.拿布局。利用LayoutInflater,但是需要一个context对象,所以都通过构造传过来。

private LayoutInflater inflater;private Context context;

public  ListAdapter(ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean> list, Context context){         this.list=list;        this.context=context;        inflater=LayoutInflater.from(context);}

2.现在已经有了布局和数据,那么就可以在加载一个布局,然后找到控件,修改里面的内容,set可以了。

view=inflater.inflate(R.layout.listitem,null);
//第四个方法很重要很重要
 @Override    public View getView(int position, View view, ViewGroup parent) {        viewHolder viewHolder;        manager= Playmanager.getinstance();        final int Position=position;        if(view==null)        {
                 //加载了这个子布局            view=inflater.inflate(R.layout.listitem,null);            viewHolder=new viewHolder();
//找到这个布局的子控件            viewHolder.tv1=view.findViewById(R.id.textView4song);            viewHolder.tv2=view.findViewById(R.id.textViewname);            viewHolder.imag=view.findViewById(R.id.imageView5);            view.setTag(viewHolder);        }        else            {                viewHolder= (ListAdapter.viewHolder) view.getTag();            }       final Button btstart= view.findViewById(R.id.start);
         //  修改子布局的内容        viewHolder.tv1.setText(list.get(position).getSongname());        viewHolder. tv2.setText(list.get(position).getSingername());        Picasso.with(context)                .load(list.get(position).getAlbumpic_small())                .error(R.mipmap.ic_launcher)                .placeholder(R.drawable.dibu8)                .into(viewHolder.imag);        view.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {               list.get(Position).getUrl();                Log.e("msg","list.get(Position).getUrl()"+list.get(Position).getUrl());                 manager.cutmusic(list.get(Position).getUrl());                if ( onclick != null) {                    onclick.click(1);                }                Log.e("msg","onclick"+onclick);            }        });        return view;    }


六、看fragment代码,获取数据,同时传context,context在framgent中只需要自己加载相应布局一个view就可以拿到final Context context=view.getContext();


//这个是核心代码

   list1= (ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean>) response.body().getShowapi_res_body().getPagebean().getSonglist();                TextView TV=view.findViewById(R.id.Retorytext4);               final Context context=view.getContext();                list.setAdapter(new ListAdapter(list1,context));
//Fragment的全部代码

public class fram_0 extends Fragment{    public View view;    public ListView list;    public ListAdapter listAdapter;           private PlayerActivity activty;    private int a;    private Bundle bundle;    ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean> list1;    PlayerActivity Play;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)    {        view = inflater.inflate(R.layout.layout_0, container, false);        list=view.findViewById(R.id.listview);        query();        click();        return view;    }public void set(int a){    this.a=a;}    @Override    public void onAttach(Context context) {        Log.e("msg","Fragment:onAttach");        super.onAttach(context);    }    @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        Log.e("msg","Fragment:onCreate");        super.onCreate(savedInstanceState);    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        Log.e("msg","Fragment:onActivityCreated");        super.onActivityCreated(savedInstanceState);    }    @Override    public void onStart() {        Log.e("msg","Fragment:onStart");        super.onStart();    }    @Override    public void onResume() {        Log.e("msg","Fragment:onResume");        super.onResume();    }    @Override    public void onPause() {        Log.e("msg","Fragment:onPause");        super.onPause();    }    @Override    public void onStop() {        Log.e("msg","Fragment:onStop");        super.onStop();    }    @Override    public void onDestroyView() {        Log.e("msg","Fragment:onDestroyView");        super.onDestroyView();    }    @Override    public void onDestroy() {        Log.e("msg","Fragment:onDestroy");        super.onDestroy();    }    @Override    public void onDetach() {        Log.e("msg","Fragment:onDetach");        super.onDetach();    }    private void query()    {//        http://route.showapi.com/213-4?showapi_appid=48962&topid=5&showapi_sign=9ad486a2461e47f4b3391171911f5b4b        //1.创建Retrofit对象        Retrofit retrofit = new Retrofit.Builder()                .addConverterFactory(GsonConverterFactory.create())//解析方法                .baseUrl("http://route.showapi.com/")//主机地址                .build();        PlayerActivity.retrofitinter retrofitinter=retrofit.create(PlayerActivity.retrofitinter.class);        Call<josntop> call=retrofitinter.getResult("48962","5","9ad486a2461e47f4b3391171911f5b4b");        call.enqueue(new Callback<josntop>() {                @Override            public void onResponse(Call<josntop> call, Response<josntop> response)            {                list1= (ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean>) response.body().getShowapi_res_body().getPagebean().getSonglist();                TextView TV=view.findViewById(R.id.Retorytext4);               final Context context=view.getContext();                list.setAdapter(new ListAdapter(list1,context));            }            @Override            public void onFailure(Call<josntop> call, Throwable t) {            }        });    }    public interface retrofitinter    {        @GET("/213-4/")        Call<josntop> getResult(@Query("showapi_appid") String showapi_appid, @Query("topid") String topid, @Query("showapi_sign") String showapi_sign);    }
七、Listview适配器的优化,这是必须的尤其这种大数据展示

1.第一个优化view的创建,一个是防止每次都将ListView的每一行的布局文件实例化,由于getview会反复调用。打个log就可以知道中间第二参数view的特点,这个view类似于一个循环生成的位置,等于如果第一用这个view,那么会它的值为null,在后面的时候我们会发现2.优化findviewbyid,由于这个非常耗时的,前面已经将xml文件解析出来了,那么

xml文件被解析的时候,只要被创建出来了,其孩子的id就不会改变了。根据这个特点,可以将孩子id存入到指定的集合中,每次就可以直接取出集合中对应的元素就可以了。这样就可以了

1、优化一:复用convertView

Android系统本身为我们考虑了ListView的优化问题,在复写的Adapter的类中,比较重要的两个方法是getCount()和getView()。界面上有多少个条显示,就会调用多少次的getView()方法;因此如果在每次调用的时候,如果不进行优化,每次都会使用View.inflate(….)的方法,都要将xml文件解析,并显示到界面上,这是非常消耗资源的:因为有新的内容产生就会有旧的内容销毁,所以,可以复用旧的内容。

优化:

在getView()方法中,系统就为我们提供了一个复用view的历史缓存对象convertView,当显示第一屏的时候,每一个item都会新创建一个view对象,这些view都是可以被复用的;如果每次显示一个view都要创建一个,是非常耗费内存的;所以为了节约内存,可以在convertView不为null的时候,对其进行复用

2、优化二:缓存item条目的引用——ViewHolder

  findViewById()这个方法是比较耗性能的操作,因为这个方法要找到指定的布局文件,进行不断地解析每个节点:从最顶端的节点进行一层一层的解析查询,找到后在一层一层的返回,如果在左边没找到,就会接着解析右边,并进行相应的查询,直到找到位置(如图)。因此可以对findViewById进行优化处理,需要注意的是:

》》》》特点:xml文件被解析的时候,只要被创建出来了,其孩子的id就不会改变了。根据这个特点,可以将孩子id存入到指定的集合中,每次就可以直接取出集合中对应的元素就可以了。在参数里面没有控件的位置,只有view,所以没有办法对它进行向view一样判断,这个时候我们可以将它与view绑定起来,如何绑定呢?

view.setTag(viewHolder);
class viewHolder{    TextView tv1, tv2;    ImageView imag;}



public View getView(int position, View view, ViewGroup parent) 



@Overridepublic View getView(int position, View view, ViewGroup parent) {    viewHolder viewHolder;    manager= Playmanager.getinstance();    final int Position=position;    if(view==null)    {        view=inflater.inflate(R.layout.listitem,null);        viewHolder=new viewHolder();        viewHolder.tv1=view.findViewById(R.id.textView4song);        viewHolder.tv2=view.findViewById(R.id.textViewname);        viewHolder.imag=view.findViewById(R.id.imageView5);        view.setTag(viewHolder);    }    else        {            viewHolder= (ListAdapter.viewHolder) view.getTag();        }   final Button btstart= view.findViewById(R.id.start);    viewHolder.tv1.setText(list.get(position).getSongname());    viewHolder. tv2.setText(list.get(position).getSingername());    Picasso.with(context)            .load(list.get(position).getAlbumpic_small())            .error(R.mipmap.ic_launcher)            .placeholder(R.drawable.dibu8)            .into(viewHolder.imag);    view.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {           list.get(Position).getUrl();            Log.e("msg","list.get(Position).getUrl()"+list.get(Position).getUrl());             manager.cutmusic(list.get(Position).getUrl());            if ( onclick != null) {                onclick.click(1);            }            Log.e("msg","onclick"+onclick);        }    });    return view;}

八、同时可以给listview的每一条子条目设置监听多好,就是这么简单

 view.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {           list.get(Position).getUrl();            Log.e("msg","list.get(Position).getUrl()"+list.get(Position).getUrl());             manager.cutmusic(list.get(Position).getUrl());            if ( onclick != null) {                onclick.click(1);            }            Log.e("msg","onclick"+onclick);        }    });
好了先写到里了,完事走人。


原创粉丝点击