Andriod 实现一个类微信聊天界面 (二)

这次实验基于上次的Andriod实验一完成   实验(一) 传送门

这次是要在之前实现的Fragment框架中添加RecycleView控件,用于实现下拉列表、瀑布流、上拉下拉刷新的功能。

先来介绍一下什么是RecycleView:
 
 

 

【Android 控件 RecyclerView】

概述
 
从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活。RecyclerView的官方定义如下:

A flexible view for providing a limited window into a large data set.

从定义可以看出,flexible(可扩展性)是RecyclerView的特点。

RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字Recyclerview即回收view也可以看出。

RecyclerView的优点
RecyclerView并不会完全替代ListView(这点从ListView没有被标记为@Deprecated可以看出),两者的使用场景不一样。但是RecyclerView的出现会让很多开源项目被废弃,例如横向滚动的ListView, 横向滚动的GridView, 瀑布流控件,因为RecyclerView能够实现所有这些功能。

比如:有一个需求是屏幕竖着的时候的显示形式是ListView,屏幕横着的时候的显示形式是2列的GridView,此时如果用RecyclerView,则通过设置LayoutManager一行代码实现替换。

RecylerView相对于ListView的优点罗列如下:

RecyclerView封装了viewholder的回收复用,也就是说RecyclerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
直接省去了listview中convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecyclerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。
设置布局管理器以控制Item的布局方式,横向、竖向以及瀑布流方式
例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还StaggeredGridLayoutManager等)。也就是说RecyclerView不再拘泥于ListView的线性展示方式,它也可以实现GridView的效果等多种效果。
可设置Item的间隔样式(可绘制)
通过继承RecyclerView的ItemDecoration这个类,然后针对自己的业务需求去书写代码。
可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecyclerView有其自己默认的实现。
但是关于Item的点击和长按事件,需要用户自己去实现。

转自:https://www.jianshu.com/p/4f9591291365

了解了RecycleView的基本功能,再对自己的程序加以调整适应,就能实现一个很简单的列表下拉功能。

其中有几个重要的文件需要添加

( 一定是添加 ,我之前莫名其妙在MainActivity中修改了很多代码,然后就死活运行不出来! 写好的MainActivity除了代码结构发生改变,否则不要轻易去动他!)。

 

HomeAdapter.java (新建适配器,以便在界面中添加控件)

 

package com.example.jay10_8;

import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {
    private List<String> mList;
    private Context mContext;

    public HomeAdapter(Context mContext, List<String> mList) {
        this.mContext = mContext;
        this.mList = mList;
    }


    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.tab01_recycle_item,parent,false);
        return new MyViewHolder(itemView);
    }


    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.nametv.setText(mList.get(position));
        final String content = mList.get(position);
        String stickyData = mList.get(position);

        holder.nametv.setText(stickyData);

        if (position == 0) {
            holder.nametv.setVisibility(View.VISIBLE);
            holder.nametv.setText(stickyData);
            holder.itemView.setTag(1);
        } else {
            if (!TextUtils.equals(stickyData, mList.get(position - 1))) {
                holder.nametv.setVisibility(View.VISIBLE);
                holder.nametv.setText(stickyData);
                holder.itemView.setTag(2);
            } else {
                holder.nametv.setVisibility(View.GONE);
                holder.itemView.setTag(3);
            }
        }
        holder.itemView.setContentDescription(stickyData);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "你选中的是: " + content, Toast.LENGTH_SHORT).show();
            }
        });

    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {

        private TextView nametv;


        public MyViewHolder(View itemView) {
            super(itemView);
            nametv = itemView.findViewById(R.id.tab01_header_view);

        }
    }


    public interface OnItemClickListener {
        void OnItemClick(View view, List<String> mList);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        // 供外部访问
    }

}


item.xml (用以显示新建的RecycleView)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FFFFFF"
        android:layout_gravity="center_vertical"
        />


</LinearLayout>

item_include.xml (单独显示顶部磁吸的标题栏)
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tab01_header_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"

    android:text="@string/Hearthstone"
    android:textColor="#BC1212"
    android:textStyle="italic"
    android:textSize="25sp"
    android:background="#E0F8EB">

</TextView>
item_recycle_item (一个可以被选择的LinearLayout,添加列表显示数据)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:orientation="vertical">

    <include layout="@layout/tab01_include" />

</LinearLayout>

然后就是需要修改一下你说需要修改的tab中的Fragment.java文件了,我这里以WeixinFragment为例:

package com.example.jay10_8;

import android.os.Bundle;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link WeixinFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class WeixinFragment extends Fragment {

    private List<String> mList;

    private View view;

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public WeixinFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment BlankFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static WeixinFragment newInstance(String param1, String param2) {
        WeixinFragment fragment = new WeixinFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }
    private void InitRecyclerView(){
        RecyclerView mRecyclerView = view.findViewById(R.id.tab01_1);

        HomeAdapter mHomeAdapter = new HomeAdapter(getActivity(), mList);
        mRecyclerView.setAdapter(mHomeAdapter);
        // 设置布局管理器
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL,false);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        // 设置 item 增加和删除时的动画
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

//        mHomeAdapter.setOnItemClickListener(new HomeAdapter.OnItemClickListener(){
//            @Override
//            public void OnItemClick(View view, List<String> mList) {
//                //此处进行监听事件的业务处理
//                Toast.makeText(getActivity(),"我是item",Toast.LENGTH_SHORT).show();
//            }
//
//        });

    }

    private List<String> getList() {
        List<String> list = new ArrayList<>();
        List<String> list1 = new ArrayList<>();
        list.add("吉安娜");
        list.add("陈康王");
        list.add("麦格尼");
        list.add("卡德加");
        list.add("安度因");
        list.add("ddg");
        list.add("陈凯歌");
        list.add("玛法里奥");
        list.add("乌瑟尔");
        list.add("吉安娜");
        list.add("陈康王");
        list.add("麦格尼");
        list.add("卡德加");
        list.add("安度因");
        list.add("ddg");
        list.add("陈凯歌");
        list.add("玛法里奥");
        list.add("乌瑟尔");
        list.add("吉安娜");
        list.add("陈康王");
        list.add("麦格尼");
        list.add("卡德加");
        list.add("安度因");
        list.add("ddg");
        list.add("陈凯歌");
        list.add("玛法里奥");
        list.add("乌瑟尔");
        list.add("吉安娜");
        list.add("陈康王");
        list.add("麦格尼");
        list.add("卡德加");
        list.add("安度因");
        list.add("ddg");
        list.add("陈凯歌");
        list.add("玛法里奥");
        list.add("乌瑟尔");

        for (int i =0;i<list.size();i++){
            list1.add((i+1)+":"+list.get(i));
        }

        return list1;

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        mList = getList();
        view = inflater.inflate(R.layout.tab01, container, false);
        //对recycleview进行配置
        InitRecyclerView();



        return view;
    }
}

 

调这个代码真的不是一蹴而就的事,花了我两天时间来看懂和适配自己文件中的参数,一定要注意函数之间的传参对应,在其他函数中如果要调用到主函数中的this.context,记得用getActivity()函数替换。。。

 
 
给一个简陋的运行结果康康:(确实很丑,懒得调了)

 
里面是随便加的一些炉石英雄和乱七八糟的东西哈哈哈hhh

 

 
调bug调的心累。。。。8说了 下把棋歇会 ~~

 
ψ(*`ー´)ψ
 
 
 

源码我放在下面了,需要的朋友可以自行下载来对照看看,如果实在有解决不了的问题,可以私信我。

源码地址:https://gitee.com/jia_jie_wang/My_RecyclerView/tree/master

 

听说点赞、收藏、一键三连的鲍勃都会送你金铜须哦~~

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值