Android RecyclerView显示不同item布局

使用RecyclerView显示ListView列表遇到的坑:子item设置match_parent,实际宽度没有全屏
解决办法:onCreateViewHolder()方法中mInflater.inflate()要把parent传进去,如:

return new RecyclerViewHolder1(mInflater.inflate(R.layout.recycler_view_item_1, parent, false));

而不能像之前使用的

inflate(R.layout.item_view,null);

运行效果:
Android RecyclerView显示不同item布局_第1张图片

实现步骤:
1,主要界面布局文件activity_main.xml:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eee"
    tools:context="com.xing.recyclerviewtest.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
RelativeLayout>

2,两个item布局文件 recycler_view_item1.xml recycler_view_item2.xml:


<android.support.v7.widget.CardView 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="wrap_content"
    android:layout_margin="8dp"
    app:cardBackgroundColor="#fff"
    app:cardCornerRadius="5dp"
    app:cardElevation="8dp">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/iv_image"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:scaleType="centerCrop"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:id="@+id/tv_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="100dp"
            android:padding="10dp"
            android:text="jisuanji"
            android:textColor="#000"
            android:textSize="18sp" />

    LinearLayout>


android.support.v7.widget.CardView>

<android.support.v7.widget.CardView 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="wrap_content"
    app:cardBackgroundColor="#fff"
    android:layout_margin="8dp"
    app:cardCornerRadius="5dp"
    app:cardElevation="5dp">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="jisuanji"
            android:textColor="#000"
            android:textSize="18sp" />

    LinearLayout>


android.support.v7.widget.CardView>

3,ActionBar上按钮


<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <item
        android:id="@+id/action_change_recycler_view"
        android:icon="@drawable/img_menu"
        android:title="@string/change_recycler_view"
        app:showAsAction="always">

        <menu>
            <item
                android:id="@+id/item_list"
                android:title="List" />
            <item
                android:id="@+id/item_grid"
                android:title="Grid" />
            <item
                android:id="@+id/item_stagger"
                android:title="Stagger" />

        menu>

    item>

menu>

4,编写RecyclerView的Adapter
RecycleViewAdapter.java

package com.xing.recyclerviewtest;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by Administrator on 2016/7/11.
 */
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context mContext;

    private LayoutInflater mInflater;

    private String[] titles;   //显示文本

    private int[] resId;           //显示图片的资源id

    public RecyclerViewAdapter(Context context, String[] titles, int[] resId) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
        this.titles = titles;
        this.resId = resId;
    }

    public enum ItemType {
        ITEM1, ITEM2
    }

    /**
     * 创建ViewHolder
     *
     * @param parent
     * @param viewType item布局的类型索引
     * @return
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == ItemType.ITEM1.ordinal()) {   //创建第一种holder
            return new RecyclerViewHolder1(mInflater.inflate(R.layout.recycler_view_item_1, parent, false));
        } else if (viewType == ItemType.ITEM2.ordinal()) {
            return new RecyclerViewHolder2(mInflater.inflate(R.layout.recycler_view_item_2, parent, false));
        }
        return null;
    }

    /**
     * 绑定数据至holder
     *
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        String text = titles[position];
        int id = resId[position];
        //根据holder的类型不同,显示不同的数据
        if (holder instanceof RecyclerViewHolder1) {
            ((RecyclerViewHolder1) holder).imageView.setImageResource(id);
            ((RecyclerViewHolder1) holder).textView.setText(text);
        } else if (holder instanceof RecyclerViewHolder2) {
            ((RecyclerViewHolder2) holder).textView.setText(text);
        }
    }

    @Override
    public int getItemCount() {
        return titles.length;
    }

    /**
     * 根据当前的位置索引加载不同的item布局
     *
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        int num = position % 2;
        if (num == 0) {
            return ItemType.ITEM1.ordinal();
        } else {
            return ItemType.ITEM2.ordinal();
        }
    }

    /**
     * 第一种item对应的holder
     */
    public static class RecyclerViewHolder1 extends RecyclerView.ViewHolder {

        ImageView imageView;

        TextView textView;

        /**
         * @param itemView 表示根布局视图
         */
        public RecyclerViewHolder1(View itemView) {
            super(itemView);
            imageView = (ImageView) itemView.findViewById(R.id.iv_image);
            textView = (TextView) itemView.findViewById(R.id.tv_text);
        }
    }

    /**
     * 第2种item对应的holder
     */
    public static class RecyclerViewHolder2 extends RecyclerView.ViewHolder {

        TextView textView;

        /**
         * @param itemView 表示根布局视图
         */
        public RecyclerViewHolder2(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.tv_text);
        }
    }


}

5,MainActivity.java
使用发广播的形式,更换RecyclerView显示形式,主要考虑到更换布局的操作可能不在同一个界面上,例如放在设置界面上。

package com.xing.recyclerviewtest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;

    private String[] titles = {"RecyclerView显示不同类型item布局", "打造 Material Desgin 风格 App",
            "面向对象程序编程", "一句话解释栈和队列的区别:东西吃多了,吐是栈,拉是队列!", "Android 从入门到放弃",
            "餐厅只接受手机支付而“谢绝现金”被认定违法", "Android", "Java程序设计", "数据结构", "Linux从入门到精通"
    };

    private int[] resId = {R.drawable.p1, R.drawable.p2, R.drawable.p2, R.drawable.p2, R.drawable.p1,
            R.drawable.p2, R.drawable.p2, R.drawable.p2, R.drawable.p1, R.drawable.p2, R.drawable.p2,
            R.drawable.p2};

    private LinearLayoutManager linearLayoutManager;

    private RecyclerViewAdapter adapter;

    private ChangeLayoutReceiver mReceiver;  //用于更改RecyclerView显示的广播接收者

    private static final String ACTION_CHANGE_LAYOUT = "com.xing.recylerview.ACTION_CHNAGE_LAYOUT";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        registerLayoutReceiver();
    }


    private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    }

    private void initData() {
        linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        adapter = new RecyclerViewAdapter(this, titles, resId);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mRecyclerView.setAdapter(adapter);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case R.id.item_list:
                changeRecyclerViewLayout(0);
                break;
            case R.id.item_grid:
                changeRecyclerViewLayout(1);
                break;
            case R.id.item_stagger:
                changeRecyclerViewLayout(2);
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void changeRecyclerViewLayout(int index) {
        Intent intent = new Intent();
        intent.setAction(ACTION_CHANGE_LAYOUT);
        switch (index) {
            case 0:
                intent.putExtra("index", 0);
                break;
            case 1:
                intent.putExtra("index", 1);
                break;
            case 2:
                intent.putExtra("index", 2);
                break;
        }
        sendBroadcast(intent);
    }


    class ChangeLayoutReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_CHANGE_LAYOUT.equals(action)) {
                int index = intent.getIntExtra("index", 0);
                updateLayoutManger(index);
            }
        }
    }

    private void updateLayoutManger(int index) {
        switch (index) {
            case 0:
                mRecyclerView.setLayoutManager(linearLayoutManager);
                mRecyclerView.setAdapter(adapter);
                break;
            case 1:
                mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false));
                mRecyclerView.setAdapter(adapter);
                break;
            case 2:
                mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
                mRecyclerView.setAdapter(adapter);
                break;
        }
    }

    /**
     * 在onCreate中注册广播
     */
    private void registerLayoutReceiver() {
        mReceiver = new ChangeLayoutReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_CHANGE_LAYOUT);
        registerReceiver(mReceiver, filter);
    }


    /**
     * 取消注册广播
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }
}

你可能感兴趣的:(Android RecyclerView显示不同item布局)