Andriod 實現一個類微信聊天介面 (二)

凋敝臣楷鴿發表於2020-11-05

次實驗基於上次的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

 

聽說點贊、收藏、一鍵三連的鮑勃都會送你金銅須哦~~

在這裡插入圖片描述

相關文章