Android Fragment + RecyclerView瀑布流佈局

2020-09-22 15:01:56

1、瀑布流效果圖

2、使用RecyclerView實現瀑布流佈局

在這裡插入圖片描述

2.1 RecyclerView的用法

RecyclerView與ListView 類似,都使用Adapter(介面卡)來生成列表項,不同的是RecyclerView 使用的是改進的RecyclerView.Adapter,RecyclerView.Adapter需要實現三種方法。

2.1.1 onCreteViewHolder(ViewGroup viewGroup,int i);

此方法用於建立列表項元件。

2.1.2 onBindViewHolder(ViewHolder viewHolder,int i);

此方法用於負責為列表項元件繫結資料,每次元件重新顯示出來都會重新執行該方法。

2.1.3 getItemCount();

該方法的返回值決定包含多少個列表項。

2.2 Adapter程式碼範例

public class StaggeredGridAdater extends RecyclerView.Adapter<StaggeredGridAdater.HomeViewHolder> {

    private Context mContext;
    private List<Home> homeList = new ArrayList<>();

    public StaggeredGridAdater(Context context,List<Home> homeList){
        this.mContext = context;
        this.homeList = homeList;
    }

    //建立列表元件
    @NonNull
    @Override
    public StaggeredGridAdater.HomeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item,null);
        return new StaggeredGridAdater.HomeViewHolder(view,this);
    }

    //繫結資料
    @Override
    public void onBindViewHolder(@NonNull HomeViewHolder holder, int position) {
        holder.imageIdIv.setImageResource(homeList.get(position).getImageId());
        holder.nameTv.setText(homeList.get(position).getName());
    }

    //返回列表資料總數
    @Override
    public int getItemCount() {
        return homeList.size();
    }


    public class HomeViewHolder extends RecyclerView.ViewHolder{
        TextView nameTv;
        ImageView imageIdIv;
        private RecyclerView.Adapter adapter;
        public HomeViewHolder(@NonNull View itemView,RecyclerView.Adapter adapter) {
            super(itemView);
            this.nameTv = itemView.findViewById(R.id.home_item_text);
            this.imageIdIv = itemView.findViewById(R.id.home_item_mage);
            this.adapter = adapter;
        }
    }
}

為了有效管理列表項所包含的子元件,額外定義了一個HomeViewHolder類。通過onCreateViewHolder()建立列表項
傳入。

2.3 Fragment(或Activity)程式碼

public class HomeFragment extends Fragment {

    private RecyclerView recyclerView;
    private List<Home> homeList = new ArrayList<>();

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_home, container, false);

        recyclerView = root.findViewById(R.id.home_recycler);
        //設定RecyclerView保持固定大小,這樣可以優化RecyclerView的效能
        recyclerView.setHasFixedSize(true);

        initData();

        //設定瀑布流佈局為2列,垂直方向滑動
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));

        StaggeredGridAdater staggeredGridAdater = new StaggeredGridAdater(this.getActivity(),homeList);

        //建立分割線物件
        recyclerView.addItemDecoration(new MyDecoration());

        recyclerView.setAdapter(staggeredGridAdater);

        return root;
    }

    //資料來源
    private void initData() {
        String[] names = new String[]{"車位查詢","車位預定","與車間距","防盜警報","停車時長","車位查詢","車位預定","與車間距","防盜警報","停車時長"};
        int[] ImageId = new int[]{R.drawable.car1,R.drawable.car2,R.drawable.car3,R.drawable.car4,R.drawable.car5,R.drawable.car1,R.drawable.car2,R.drawable.car3,R.drawable.car4,R.drawable.car5};
        for(int i = 0 ;i < names.length ; i++){
            this.homeList.add(new Home(names[i],ImageId[i]));
        }
    }

    //分割線的類
    class MyDecoration extends RecyclerView.ItemDecoration{
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state){
            super.getItemOffsets(outRect,view ,parent,state);
            int gap = getResources().getDimensionPixelSize(R.dimen.dividerHeight);//5dp
            outRect.set(gap,gap,gap,gap);
        }
    }

}

2.4 Home類

public class Home {
    private String name;
    private int ImageId;

    public Home(String name,int ImageId){
        this.name = name;
        this.ImageId = ImageId;
    }

    public int getImageId() {
        return ImageId;
    }

    public void setImageId(int imageId) {
        ImageId = imageId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.5 主佈局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">

    <!--android:divider 分割線-->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/home_recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="56dp"
        android:background="@color/colorWhite">
    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

2.6 item子佈局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/home_item_mage"
        android:scaleType="centerCrop"/>

    <TextView
        android:id="@+id/home_item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="2dp"
        android:layout_gravity="left|bottom"
        android:padding="12dip"
        android:background="#85000000"
        android:textColor="#ffffffff"
        android:text="Golden Gate"
        android:textStyle="bold"/>
</FrameLayout>