安卓 列表listview

          当内容超过屏幕大小的时候,我们需要让屏幕容纳足够的展示,所以我们引入了一个控件,可滑动的控件,当然这里可以使用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>



<ImageView
android: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) 



@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;
}

八、同时可以给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);


        }
    });
好了先写到里了,完事走人。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值