ViewPager+GridView实现商品分类

来源:互联网 发布:初中生 18cm 知乎 编辑:程序博客网 时间:2024/04/30 09:00
本程序利用ViewPager+GridView实现了类似美团中的商品分类的功能

程序效果如图所示




本程序用的核心技术:ViewPager   GridView  自定义控件


本程序实现的基本步骤
1. 加载项目里用到的资源放到集合里,以方便后续使用
2. 初始化两个GridView控件
3. 初始化VIewPager控件



代码框架



实现步骤
0.在res/values/下建一个arrays.xml文件,完成后在里面添加数据资源,并将图片放到mipmap文件下
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <!-- 一个array就是一个数组,name就是数组名,item就是一个元素,
   里面包裹的元素重上到下就是角标从0开始递增-->
    <array name="home_bar_labels">
        <item>美食</item>
        <item>电影</item>
        <item>酒店</item>
        <item>休闲娱乐</item>
        <item>自助餐</item>
        <item>KTV</item>
        <item>蛋糕甜点</item>
        <item>旅游</item>
        <item>购物</item>
        <item>摄影写真</item>
        <item>丽人</item>
        <item>生活服务</item>
        <item>门票</item>
        <item>抽奖公益</item>
        <item>今日新单</item>
        <item>全部分类</item>
    </array>
     <!--图片资源会在最后给链接-->
    <array name="home_bar_icon">
        <item>@mipmap/icon_home_food_99</item>
        <item>@mipmap/icon_home_movie_29</item>
        <item>@mipmap/icon_home_hotel_300</item>
        <item>@mipmap/icon_home_happy_2</item>
        <item>@mipmap/icon_home_self_189</item>
        <item>@mipmap/icon_home_ktv_31</item>
        <item>@mipmap/icon_home_93</item>
        <item>@mipmap/icon_home_400</item>
        <item>@mipmap/icon_home_3</item>
        <item>@mipmap/icon_home_37</item>
        <item>@mipmap/icon_home_42</item>
        <item>@mipmap/icon_home_life_46</item>
        <item>@mipmap/icon_home_18</item>
        <item>@mipmap/icon_home_16</item>
        <item>@mipmap/icon_home_999</item>
        <item>@mipmap/icon_home_all_0</item>

    </array>
</resources>

1.创建实体类HomeIconInfo
/**
 * date:2016/12/15
 * author:耿佳伟
 * function:一个装载主页商品分类的容器,一个装图片,一个装文字
 */
public class HomeIconInfo {
    String iconName;
    int iconId;

    public HomeIconInfo() {
    }

    public HomeIconInfo(String iconName, int iconId) {
        this.iconName = iconName;
        this.iconId = iconId;
    }

    public String getIconName() {
        return iconName;
    }

    public void setIconName(String iconName) {
        this.iconName = iconName;
    }

    public int getIconId() {
        return iconId;
    }

    public void setIconId(int iconId) {
        this.iconId = iconId;
    }
}
2.在res/layout/下创建home_grid_view.xml文件
<?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="match_parent"
    >
    <!--定义一行显示4恶搞条目.因为GridView是放在ViewPager里的,
    所以即便填充父窗体,大小也会被ViewPager给限制-->
    <GridView
        android:id="@+id/gdv_Show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="4"
        ></GridView>
</LinearLayout>
3.创建GridView的适配器
     先创建适配器下的布局文件
<?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="match_parent"
             android:orientation="vertical"
    >
    <!--每个文本上面是图片,下面是文本-->
    <ImageView
        android:id="@+id/imgShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>

    <TextView
        android:id="@+id/txtShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>
</LinearLayout>

     完成后创建MyGridViewAdapter类

/**
 * date:2016/12/15
 * author:耿佳伟
 * function:商品分类的适配器
 */
public class MyGridViewAdapter extends BaseAdapter {
    //装数据的容器,没有数据,通过构造方法,把外界的数据加载到这里
    private List<HomeIconInfo> mInfos new ArrayList<>();
    //上下文
    private Context context;

    //生成构造方法
    public MyGridViewAdapter(List<HomeIconInfo> infos, Context context) {
        mInfos = infos;
        this.context = context;
    }

    //根据需求,显示对应数量的item
    @Override
    public int getCount() {
        return mInfos.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //把一个itemxml布局转换为一个View资源
        View view = LayoutInflater.from(context).inflate(R.layout.item_gridnull);
        HomeIconInfo info = mInfos.get(position);
        //初始化ImageView对象,设置图片资源
        ImageView imageView = (ImageView) view.findViewById(R.id.imgShow);
        imageView.setImageResource(info.getIconId());
        //初始化Textview对象,设置文本资源
        TextView textView = (TextView) view.findViewById(R.id.txtShow);
        textView.setText(info.getIconName());
        return view;
    }
}



4.创建ViewPager的适配器
/**
 * date:2016/12/15
 * author:耿佳伟
 * function:ViewPager的适配器类
 */
public class MyPagerAdapter extends PagerAdapter {
    //外界传来的集合数据
    private List<View> mViews =new ArrayList<>();
    //构造方法进行容器数据的初始化,必须把外界的数据传进来,ViewPager进行加载显示
    //提示:有些参数没有数据,但是代码中用到了,就需要使用构造放啊发

    public MyPagerAdapter(List<View> views) {
        mViews = views;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        //防止角标越界
        position %=mViews.size();
       //从容器中那数据
        View view = mViews.get(position);
        //把控件对象放到ViewPager容器中,进行显示
        container.addView(view);
        //将控件返回,方便销毁
       return view;
    }

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

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        //防止角标越界
        position %=mViews.size();
        //把不用的View对象销毁,防止内存泄漏
        container.removeView(mViews.get(position));
    }
}
5.创建自定义控件类indictor
     由于自定义控件不是本次重点,如有不懂详见http://blog.csdn.net/dubuwucool/article/details/53490218
/**
 * date:2016/12/15
 * author:耿佳伟
 * function:自定义View 用来显示ViewPager下面的圆
 */
public class Indictor extends View {
    //定义一个实体圆
    private Paint FillPaint;
    //一个空心圆
    private Paint StrokePaint;
    //圆的半径
    private int radius 5;
    //圆的数量
    private int number 2;
    //实体圆的颜色
    private int FillColor = Color.GREEN;
    //空心圆的颜色
    private int StrokeColor = Color.GRAY;
    //平移的距离
    private float offset;

    public Indictor(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    public Indictor(Context context) {
        super(context);
        initPaint();
    }

    public Indictor(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        initPaint();
        //画个实心圆
        canvas.drawCircle(60 offset60radiusFillPaint);
        ////画多个空心圆
       for (int i = 0; i < number; i++) {
            canvas.drawCircle(60 radius * i, 60radiusStrokePaint);
        }
    }

    public void setOffset(int position, float positionOffset) {
        //防止角标越界
        position = position % number;

        offset = position * radius;
        //position是从0开始递增,而number则是从1开始递增,当position==number-1时,实心圆滑动到了 最后一个,
       //这是取消掉positionOffset*3*r的滑动效果,将偏移量重新设定为position*3*r即可。
       if (position == (number 1)) {
            offset = position * radius;
        }
        //关键一点,重新绘制自定义View的方法,十分常用
        invalidate();
    }

    //对画笔进行初始化设置
    private void initPaint() {
        //创建画笔对象
       FillPaint new Paint();
        //设置抗锯齿
       FillPaint.setAntiAlias(true);
        //设置画笔样式
       FillPaint.setStyle(Paint.Style.FILL);
        //设置画笔颜色
       FillPaint.setColor(FillColor);
        //设置画笔宽度
       FillPaint.setStrokeWidth(2);


        StrokePaint new Paint();
        StrokePaint.setAntiAlias(true);
        StrokePaint.setStyle(Paint.Style.STROKE);
        StrokePaint.setColor(StrokeColor);
        StrokePaint.setStrokeWidth(2);
    }
}
6.主窗体布局
<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".activity.MainActivity">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="200dp">
    </android.support.v4.view.ViewPager>

    <com.dubuwucool.viewpagerradiogroupdemo.indictor.Indictor
        android:id="@+id/indictor"
        android:layout_width="100dp"
        android:layout_height="60dp"
        android:layout_alignBottom="@+id/viewPager"
        android:layout_centerHorizontal="true"/>
</RelativeLayout>

7.主窗体代码
public class MainActivity extends AppCompatActivity {
    //创建两个集合用来添加数据
    private List<HomeIconInfo> one new ArrayList<>();
    private List<HomeIconInfo> two new ArrayList<>();

    //ViewPager要用到的集合 添加GridView
    private List<View> views new ArrayList<>();
    //声明自定义控件
    private Indictor mIndictor;
    //声明ViewPager
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化数据
        initData();
        //初始化控件
        initView();
    }

    /**
     * 初始化GirdView的数据,这些图片,文本数据(可以改成字符串),放到我们的activity里会导致
     代码量太大,不好阅读,所以我们把它放到resources.xml文件里
     */
    private void initData() {
        //通过activity的静态方法getResources,获取resources.xml的资源
       //什么样的资源定义与之相对应的数组
        String[] name = getResources().getStringArray(R.array.home_bar_labels);
        //回去图片数组资源数组,方法是obtainTypedArray
        TypedArray typedArray = getResources().obtainTypedArray(R.array.home_bar_icon);
        //由于一个GridView,显示2,每行四个,所以一个GridView16个数据(图片+文字),
        //分别撞到不同的集合
       for (int i = 0; i < name.length; i++) {
            if (i < 8) {
                //把数据装载到第一个集合中,给第一个GridView
                HomeIconInfo homeIconInfo = new HomeIconInfo(name[i], typedArray.getResourceId(i, 0));
                one.add(homeIconInfo);
            } else {
                //把数据装载到第二个集合中,给第二个GridView
                HomeIconInfo homeIconInfo = new HomeIconInfo(name[i], typedArray.getResourceId(i, 0));
                two.add(homeIconInfo);
            }
        }
    }

    private void initView() {
        //第一个GridView
        //把所有GridView的布局资源转换为View对象
        View view1 = getLayoutInflater().inflate(R.layout.home_grid_viewnull);
        //从装有GridViewView对象中查找GridView对象
        GridView gridView1 = (GridView) view1.findViewById(R.id.gdv_Show);
        //GridView设置适配器
        MyGridViewAdapter adapter = new MyGridViewAdapter(onethis);
        gridView1.setAdapter(adapter);
        gridView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this"这是第+ position + "", Toast.LENGTH_SHORT).show();
            }
        });

        //第二个GridView
        //把所有GridView的布局资源转换为View对象
        View view2 = getLayoutInflater().inflate(R.layout.home_grid_viewnull);
        //从装有GridViewView对象中查找GridView对象
        GridView gridView2 = (GridView) view2.findViewById(R.id.gdv_Show);
        //GridView设置适配器
        MyGridViewAdapter adapter2 = new MyGridViewAdapter(twothis);
        gridView2.setAdapter(adapter2);
        //设置GridView的点击事件
        gridView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this"这是第+ position + "", Toast.LENGTH_SHORT).show();
            }
        });
        //为集合添加数据
       views.add(gridView1);
        views.add(gridView2);
        //ViewPager初始化
       mViewPager = (ViewPager) findViewById(R.id.viewPager);
        //ViewPager设置适配器
        MyPagerAdapter myAdapter = new MyPagerAdapter(views);
        mViewPager.setAdapter(myAdapter);
        //初始化自定义控件
       mIndictor = (Indictor) findViewById(R.id.indictor);
        //ViewPager的监听
       mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            //当页面滑动时
           @Override
            //第一个参数 item位置
           // 第二个参数 偏移的百分比  这个百分比永远接近于1
            // 第三个参数 偏移量
           public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                mIndictor.setOffset(position, positionOffset);
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }
}


补充:本程序的图片资源

链接:http://pan.baidu.com/s/1boz5n91 密码:ffyg







0 0
原创粉丝点击