安卓布局 Recycleview

来源:互联网 发布:刺客信条4a卡优化 编辑:程序博客网 时间:2024/05/16 04:55

     RecyclerView是Google在API 21下support.V7包里的控件,用来替代ListView。


一、使用RecycleView的前提条件

        想使用RecycleView,一定要在build.gradle中引入compile 'com.android.support:recyclerview-v7:24.0.0'依赖。就是必须导入v7包。

二、使用RecycleView的优缺点

RecyclerView提供了三种布局管理器:

  • LinerLayoutManager 以垂直或者水平列表方式展示Item
  • GridLayoutManager 以网格方式展示Item
  • StaggeredGridLayoutManager 以瀑布流方式展示Item

优点:

  • RecycleView强制封装ViewHolder
  • 相当轻松的设置布局管理器以控制Item的布局方式,横向、竖向以及瀑布流方式
  • 可设置Item操作的动画,删除或者添加等
  • 通过ItemDecoration,控制Item间的间隔,可自己绘制
    • 缺点:

    • 需要自己实现OnItemClickListener点击事件(这么实用的需求,Google竟然让我们自己实现...),相当无语阿。。。
首先它的使用几乎和listview相差不大,看它的xml,直接生成一个Recycleview然后,设置宽高id即可。
<?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" />-->    
    <android.support.v7.widget.RecyclerView        android:id="@+id/Retorylistview"        android:layout_width="match_parent"        android:layout_height="match_parent" />
</LinearLayout>
二、activty界面分析
1.//首先要找到该控件
mrycleview=view.findViewById(R.id.Retorylistview);RecyclerView.LayoutManager line= new LinearLayoutManager(context);
//设置一个布局管理器,默认为垂直的
line.setOrientation(OrientationHelper.HORIZONTAL);
mrycleview.setLayoutManager(line);
2.绑定adapter
 rec=new recycleadapter();
mrycleview.setAdapter(rec);


//这个activty代码
public class fram_0 extends Fragment{    public View view;    public ListView list;    public ListAdapter listAdapter;    private RecyclerView mrycleview;    recycleadapter rec;    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);//        mrycleview=view.findViewById(R.id.Retorylistview);//        mrycleview.setItemAnimator(new DefaultItemAnimator());        rec=new recycleadapter();        activty= (PlayerActivity) getActivity();        Log.e("msg","44444444444444444444444");        rec.SetOnItemclick(new recycleadapter.Onitemlisten() {            @Override            public void onitemclick(View view, int position) {                Toast.makeText(view.getContext(), list1.get(position).getUrl()+"", Toast.LENGTH_SHORT).show();                activty.setpaly();            }        });        mrycleview.setAdapter(rec);//        rec.notifyDataSetChanged()        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);//                for(int i=0;i<list1.size();i++)//                {//                    list1.get(i).getSingername();////                            Log.e("msg", list.get(i).getSingername()+"");//                    TV.append(list1.get(i).getSingername());//////                    listAdapter.get(list,context);//                }               final Context context=view.getContext();                mrycleview=view.findViewById(R.id.Retorylistview);                RecyclerView.LayoutManager line= new LinearLayoutManager(context);                mrycleview.setLayoutManager(line);
//默认就是垂直发的//        line.setOrientation(OrientationHelper.HORIZONTAL);               rec.setdata(list1);//                list.setAdapter(listAdapter);            }            @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);    }   

三、可以看到对RecylerView的设置过程,比ListView要复杂一些,虽然代码抒写上有点复杂,但它的扩展性是极高的。在了解了RecyclerView的一些控制之后,紧接着来看看它的Adapter的写法,RecyclerView的Adapter与ListView的Adapter还是有点区别的,RecyclerView.Adapter,需要实现3个方法: 

1.onCreateViewHolder() 
这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。

第一个方法中主要进行了
1.实例化一个view。
context=parent.getContext();View view=inflater.from(parent.getContext()).inflate(R.layout.listitem,null);
2.实例化了一个viewhoider
ViewHolder holder= new ViewHolder(view);
3.获取了一个媒体播放的对象,主要是因为我需要在获得子条目时在这里面就进行播放,放在这个方法最
manager= Playmanager.getinstance();

@Override

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){    Log.e("msg","11111111111111111");    context=parent.getContext();    View view=inflater.from(parent.getContext()).inflate(R.layout.listitem,null);   ViewHolder holder= new ViewHolder(view);    manager= Playmanager.getinstance();    return holder;}
2.onBindViewHolder() 
这个方法主要用于适配渲染数据到View中。方法提供给你了一viewHolder而不是原来的convertView。

1.将要加载数据都放入到

 holder.tv1.setText(list.get(position).getSongname());    holder.tv2.setText(list.get(position).getSingername());    Picasso.with(context)            .load(list.get(position).getAlbumpic_big())            .error(R.mipmap.ic_launcher)            .placeholder(R.drawable.dibu8)            .into(holder.IV);
2.获取每一个子条目并设置监听
   View view=holder.itemView;
   view.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Toast.makeText(context,list.get(position).getSongname(),Toast.LENGTH_LONG).show();            manager.cutmusic(list.get(position).getUrl());            if(listen!=null) {                listen.onitemclick(v, position);            }        }    });}

@Overridepublic void onBindViewHolder(ViewHolder holder, final int position){      Log.e("msg","22222222222222222222");    holder.tv1.setText(list.get(position).getSongname());    holder.tv2.setText(list.get(position).getSingername());    Picasso.with(context)            .load(list.get(position).getAlbumpic_big())            .error(R.mipmap.ic_launcher)            .placeholder(R.drawable.dibu8)            .into(holder.IV);    View view=holder.itemView;    view.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Toast.makeText(context,list.get(position).getSongname(),Toast.LENGTH_LONG).show();            manager.cutmusic(list.get(position).getUrl());            if(listen!=null) {                listen.onitemclick(v, position);            }        }    });}
3. getItemCount() 
这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。接下来通过几个小的实例帮助大家更深入的了解RecyclerView的用法。
@Overridepublic int getItemCount() {    Log.e("msg","3333333333333333333333");    return list.size();}
4.// 定义内部类继承ViewHolder
class ViewHolder extends RecyclerView.ViewHolder    {        TextView tv1,tv2;        private ImageView IV;        public ViewHolder(View itemView) {            super(itemView);//            tv = (TextView)itemView.findViewById(R.id.recycleitem);//            IV=(ImageView)itemView.findViewById(R.id.imageView10);           tv1=itemView.findViewById(R.id.textView4song);            tv2=itemView.findViewById(R.id.textViewname);            IV=itemView.findViewById(R.id.imageView5);        }    }
5.定义一个接口与activty进行通信。
view.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        Toast.makeText(context,list.get(position).getSongname(),Toast.LENGTH_LONG).show();        manager.cutmusic(list.get(position).getUrl());        if(listen!=null) {            listen.onitemclick(v, position);        }    }});

public  interface Onitemlisten{    void onitemclick(View view, int position);}Onitemlisten listen;public void SetOnItemclick(Onitemlisten listen){     this.listen=listen;}
这是在fragment中进行回调接口的核心代码,
1.获取一个自己fragmnet绑定的actvity,然后调用了一个setplay方法,这是为了使播放键能跟上
activty= (PlayerActivity) getActivity();

Log.e("msg","44444444444444444444444");rec.SetOnItemclick(new recycleadapter.Onitemlisten() {    @Override    public void onitemclick(View view, int position) {        Toast.makeText(view.getContext(), list1.get(position).getUrl()+"", Toast.LENGTH_SHORT).show();        activty.setpaly();    }});

6.定义一个方法传递数据
public void setdata(ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean> list){    this.list=list;    notifyDataSetChanged();}

//这个是适配器的代码

public class recycleadapter extends RecyclerView.Adapter<recycleadapter.ViewHolder>{    private ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean> list=new ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean>();    private LayoutInflater inflater;    private Context context;    int a;    private Playmanager manager;    public void setdata(ArrayList<josntop.ShowapiResBodyBean.PagebeanBean.SonglistBean> list)    {        this.list=list;        notifyDataSetChanged();    }    public recycleadapter(int a)    {         this.a=a;    }    public recycleadapter()    {    }    public void delete(int position)    {        list.remove(position);        notifyItemRemoved(position);    }    @Override    public int getItemViewType(int position) {        return super.getItemViewType(position);    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)    {        Log.e("msg","11111111111111111");        context=parent.getContext();        View view=inflater.from(parent.getContext()).inflate(R.layout.listitem,null);       ViewHolder holder= new ViewHolder(view);        manager= Playmanager.getinstance();        return holder;    }    @Override    public void onBindViewHolder(ViewHolder holder, final int position)    {          Log.e("msg","22222222222222222222");        holder.tv1.setText(list.get(position).getSongname());        holder.tv2.setText(list.get(position).getSingername());        Picasso.with(context)                .load(list.get(position).getAlbumpic_big())                .error(R.mipmap.ic_launcher)                .placeholder(R.drawable.dibu8)                .into(holder.IV);        View view=holder.itemView;        view.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(context,list.get(position).getSongname(),Toast.LENGTH_LONG).show();                manager.cutmusic(list.get(position).getUrl());                if(listen!=null) {                    listen.onitemclick(v, position);                }            }        });    }    @Override    public int getItemCount() {        Log.e("msg","3333333333333333333333");        return list.size();    }    class ViewHolder extends RecyclerView.ViewHolder    {        TextView tv1,tv2;        private ImageView IV;        public ViewHolder(View itemView) {            super(itemView);//            tv = (TextView)itemView.findViewById(R.id.recycleitem);//            IV=(ImageView)itemView.findViewById(R.id.imageView10);           tv1=itemView.findViewById(R.id.textView4song);            tv2=itemView.findViewById(R.id.textViewname);            IV=itemView.findViewById(R.id.imageView5);        }    }    public  interface Onitemlisten    {        void onitemclick(View view, int position);    }    Onitemlisten listen;    public void SetOnItemclick(Onitemlisten listen)    {         this.listen=listen;    }}