Android ViewPager嵌套GridView实现滑动网格布局

Posted 峥嵘life

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ViewPager嵌套GridView实现滑动网格布局相关的知识,希望对你有一定的参考价值。

看了网上 ViewPager嵌套GridView实现滑动网格布局的示例,
有的太旧了,有的代码逻辑不清晰,有的运行不了,
网上的要给RecyclerView的一个旧例子跑不起来,可能是RecyclerView不是很熟吧。

这里提供一个简单示例。

一、效果图:

最后一两秒的界面,是显示Item图片按下效果,
ListView和GridView默认是无法实现的,需要写代码适配,这个另外有介绍。

二、代码:

1、布局文件

<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:orientation="vertical">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/myviewpager"
        android:layout_width="match_parent"
        android:layout_height="240dip"
        android:layout_gravity="top"
        android:scaleType="fitXY" />

    <LinearLayout
        android:id="@+id/viewGroup"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/myviewpager"
        android:gravity="center_horizontal"
        android:orientation="horizontal"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/viewGroup"
        android:onClick="jumpToActivity2"
        android:background="#0ff"
        android:textSize="30sp"
        android:gravity="center"
        android:text="其他内容" />

</RelativeLayout>

2、Item对应的Bean文件

/**
 * 表格列表Bean
 */
public class CutBean {
    private String tag;//标签,用于点击后获取对应位置
    private String title; //标题的资源id
    private int pictureId; //图片id
    private int picturePreId; //图片id

    public CutBean(String tag, String title, int pictureId) {
        this.tag = tag;
        this.title = title;
        this.pictureId = pictureId;
    }

    public CutBean(String tag, String title, int pictureId, int picturePreId) {
        this.tag = tag;
        this.title = title;
        this.pictureId = pictureId;
        this.picturePreId = picturePreId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String titleId) {
        this.title = titleId;
    }

    public int getPictureId() {
        return pictureId;
    }

    public void setPictureId(int pictureId) {
        this.pictureId = pictureId;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public int getPicturePreId() {
        return picturePreId;
    }

    public void setPicturePreId(int picturePreId) {
        this.picturePreId = picturePreId;
    }
}

3、ViewPager的Adapter

package com.liwenzhi.viewpagerandrecycleview.adapter;

import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.View;
import android.widget.GridView;

import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;


/**
 * 实现ViewPager页卡切换的适配器
 */
public class MyViewPagerAdapter extends PagerAdapter {
    private List<GridView> array;
    private Map<Integer, GridView> map; //每页的GridView对象


    /**
     * 供外部调用(new)的方法
     *
     * @param context 上下文
     * @param array   添加的序列对象
     */
    public MyViewPagerAdapter(Context context, List<GridView> array) {
        this.array = array;
    }

    public MyViewPagerAdapter(Context context, Map<Integer, GridView> map) {
        this.map = map;
    }

    @Override
    public int getCount() {
        return map.size();
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }

    @Override
    public Object instantiateItem(View arg0, int arg1) {
        ((ViewPager) arg0).addView(map.get(arg1));
        return map.get(arg1);
    }

    @Override
    public void destroyItem(View arg0, int arg1, Object arg2) {
        ((ViewPager) arg0).removeView((View) arg2);
    }


}


4、GridView的Adapter


package com.liwenzhi.viewpagerandrecycleview.adapter;

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

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.liwenzhi.viewpagerandrecycleview.R;

/**
 * 用于GridView装载数据的适配器
 */
public class AppGridViewAdapter extends BaseAdapter implements OnItemClickListener {//
    String TAG = "AppGridViewAdapter";
    private List<CutBean> mList;// 定义一个list对象
    private Context mContext;// 上下文
    public static final int APP_PAGE_SIZE = 8;// 每一页装载数据的大小
    private int page;

    /**
     * 构造方法
     *
     * @param context 上下文
     * @param list    所有APP的集合
     * @param page    当前页
     */
    public AppGridViewAdapter(Context context, List<CutBean> list, int page) {
        mContext = context;
        this.page = page;
        mList = new ArrayList<CutBean>();
        // 根据当前页计算装载的应用,每页只装载8个
        int i = page * APP_PAGE_SIZE;// 当前页的其实位置
        int iEnd = i + APP_PAGE_SIZE;// 所有数据的结束位置
        while ((i < list.size()) && (i < iEnd)) {
            mList.add(list.get(i));
            i++;
        }
    }

    public int getCount() {
        return mList.size();
    }

    public Object getItem(int position) {
        return mList.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.app_item, parent, false);
            holder = new ViewHolder(convertView);
            // 在缓冲的View对象中添加holder标签
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        CutBean cutInfo = mList.get(position);
        holder.setData(cutInfo);
        return convertView;
    }

    // 表格点击回调
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String tag = mList.get(position).getTag();

        Log.i(TAG, "onItemClick  position = " + position + ",tag = " + tag);
        // 一般不在adapter处理
        //外部处理
        if (mTagCallListener != null) {
            mTagCallListener.onClickTagView(tag);
        }
    }


    /**
     * 获取当前页面值
     */
    public int getPage() {
        return page;
    }

    /**
     * 设置当前页面值
     */
    public void setPage(int page) {
        this.page = page;
        notifyDataSetChanged();
    }

    IClickTagCallBack mTagCallListener;

    public void setItemClickTagCallListener(IClickTagCallBack tagCallListener) {
        mTagCallListener = tagCallListener;
    }

    public interface IClickTagCallBack {
        void onClickTagView(String tag);
    }


    // ViewHolder的使用,也是相当于缓冲的功能
    static class ViewHolder {
        TextView name;
        ImageView iv;

        // 传入的是一个布局重用的View对象
        public ViewHolder(View convertView) {
            // 冲缓冲中提取数据
            iv = (ImageView) convertView.findViewById(R.id.ivAppIcon);
            name = (TextView) convertView.findViewById(R.id.tvAppName);
        }

        // set方法,方便数据的显示,直接显示在屏幕中
        public void setData(CutBean bean) {
            iv.setImageResource(bean.getPictureId());
            name.setText(bean.getTitle());
        }
    }

}


5、Activity显示代码


package com.liwenzhi.viewpagerandrecycleview.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.viewpager.widget.ViewPager;

import com.liwenzhi.viewpagerandrecycleview.R;
import com.liwenzhi.viewpagerandrecycleview.adapter.AppGridViewAdapter;
import com.liwenzhi.viewpagerandrecycleview.adapter.CutBean;
import com.liwenzhi.viewpagerandrecycleview.adapter.MyViewPagerAdapter;
import com.liwenzhi.viewpagerandrecycleview.control.PageControl;


/**
 * 实现横向滑动的GridView
 */
public class MainActivity extends Activity {
    String TAG = "MainActivity";
    private static final float APP_PAGE_SIZE = 8.0f;
    private MyViewPagerAdapter adapter;
    private ViewPager viewPager;
    LayoutInflater inflater;
    private PageControl pageControl;
    private Map<Integer, GridView> map;
    List<CutBean> mCutBeanList = new ArrayList<>();
    int PageCount;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate");
        inflater = getLayoutInflater();
        initData();
        initViews();
        initEvent();
    }

    private void initData() {
        mCutBeanList.add(new CutBean("1", "插入1", R.mipmap.number1));
        mCutBeanList.add(new CutBean("2", "插入2", R.mipmap.number2));
        mCutBeanList.add(new CutBean("3", "插入3", R.mipmap.number3));
        mCutBeanList.add(new CutBean("4", "插入4", R.mipmap.number4));
        mCutBeanList.add(new CutBean("5", "插入5", R.mipmap.number5));
        mCutBeanList.add(new CutBean("6", "插入6", R.mipmap.number6));
        mCutBeanList.add(new CutBean("7", "插入7", R.mipmap.number7));
        mCutBeanList.add(new CutBean("8", "插入8", R.mipmap.number8));
        mCutBeanList.add(new CutBean("9", "插入9", R.mipmap.number9));
        mCutBeanList.add(new CutBean("10", "插入10", R.mipmap.number10));
        mCutBeanList.add(new CutBean("11", "插入11", R.mipmap.number11));
        mCutBeanList.add(new CutBean("12", "插入12", R.mipmap.number12));

        // 计算页数
        PageCount = (int) Math.ceil(mCutBeanList.size() / APP_PAGE_SIZE);
    }

    private void initEvent() {
        viewPager.setOnPageChangeListener(new MyPageChangeListener());
    }

    /**
     * 获取系统所有的应用程序,并根据APP_PAGE_SIZE生成相应的GridView页面
     */
    public void initViews() {
        //每一个创建一个GridView,放到HashMap中,左右滑动显示的时候取出对话的GridView即可
        map = new HashMap<Integer, GridView>();
        for (int i = 0; i < PageCount; i++) {
            Log.i(TAG, "initViews i = " + i);
            GridView appPage = new GridView(this);
            AppGridViewAdapter adapter = new AppGridViewAdapter(this, mCutBeanList, i);
            adapter.setItemClickTagCallListener(mItemTagCallBack);
            appPage.setNumColumns(4);//多少列,即每行多少个
            appPage.setAdapter(adapter);
            appPage.setOnItemClickListener(adapter);
            map.put(i, appPage);

        }

        ViewGroup main = (ViewGroup) inflater.inflate(R.layout.activity_main, null);
        // group是R.layou.main中的负责包裹小圆点的LinearLayout.
        ViewGroup group = (ViewGroup) main.findViewById(R.id.viewGroup);
        pageControl = new PageControl(this, (LinearLayout) group, PageCount);
        setContentView(main);

        viewPager = (ViewPager) findViewById(R.id.myviewpager);
        adapter = new MyViewPagerAdapter(this, map);
        viewPager.setAdapter(adapter);

    }

    //滑动事件回调
    class MyPageChangeListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrollStateChanged(int arg0) {
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        //滑动之后页面游标值改变
        @Override
        public void onPageSelected(int position) {
            Log.i(TAG, "onPageSelected position = " + position);
            pageControl.selectPage(position);
        }

    }

    /**
     * 条目事件的回调
     */
    AppGridViewAdapter.IClickTagCallBack mItemTagCallBack = new AppGridViewAdapter.IClickTagCallBack() {
        @Override
        public void onClickTagView(String tag) {
            Toast.makeText(MainActivity.this, "点击tag:" + tag, Toast.LENGTH_LONG).show();
            //在自己的对应TAG处理具体事务
            switch (tag) {
                case "1":
                    break;
                ///...
            }
        }
    };

    //跳转到另外一个GridView界面
    public void jumpToActivity2(View view) {
        startActivity(new Intent(this, Activity2.class));
    }

}


代码就介绍到这里,需要具体代码可以进行下载。

下载链接:

https://download.csdn.net/download/wenzhi20102321/24341981

共勉:野蛮生长才能到实现更高的高度。

以上是关于Android ViewPager嵌套GridView实现滑动网格布局的主要内容,如果未能解决你的问题,请参考以下文章

android scrollview 嵌套 viewpager 嵌套 gridview 冲突问题

Android ViewPager嵌套ViewPager滑动冲突处理方法

Android 解决viewPager中嵌套webView的滑动冲突

Android 中ViewPager嵌套RecyclerView出现滑动冲突的解决方案

Android ViewPager嵌套GridView实现滑动网格布局

android viewpager嵌套使用photoview异常问题