最近,根据项目需求,需要一个能够自动分页的导航,所以便自定义了一个自动分页的GridView。

思路:继承RelativeLayout,然后在里面放了一个viewpager和一个GridView。。。我也不会说,还是直接上代码吧

先看看你效果图,分别是2行3列和1行3列(有自定义属性,可以自己定义几行几列)

接下来直接看源代码(很简单)

 package custom.widget;

 import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout; import com.newair.automaticpagedemo.R; import java.util.ArrayList;
import java.util.List; /**
* Created by ouhimehime on 16/5/4.
* ----------自动分页的GridView----------
*/
public class AutoMaticPageGridView extends RelativeLayout { //分页所用
private ViewPager viewPager;
//导航点
private RadioGroup radioGroup;
//自定义行数
private int lines = 0;
//自定义列数
private int column = 0;
//自定义按钮样式
private int btn_res;
//自定义属性是否显示导航点
private boolean btn_isvisible;
//页数-需要动态计算
private int pages = 0;
//适配器
private BaseAutoAdapter adapter;
//Item的高度
private int itemHeight = 0; //点击事件的接口
public interface OnItemClickCallBack {
void OnItemClicked(int position, Object object);
} private OnItemClickCallBack onItemClickCallBack; public void setOnItemClickListener(OnItemClickCallBack onItemClickCallBack) {
this.onItemClickCallBack = onItemClickCallBack;
} public AutoMaticPageGridView(Context context) {
super(context);
} public AutoMaticPageGridView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
} public AutoMaticPageGridView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
} @TargetApi(Build.VERSION_CODES.LOLLIPOP)
public AutoMaticPageGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
} //初始化控件
private void init(Context context, AttributeSet attrs) {
//加载自定义属性
final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AutoMaticPageGridView);
lines = array.getInteger(R.styleable.AutoMaticPageGridView_auto_lines, 1);//行数
column = array.getInteger(R.styleable.AutoMaticPageGridView_auto_column, 4);//列数
btn_res = array.getResourceId(R.styleable.AutoMaticPageGridView_auto_button, 0);//btn的样式
btn_isvisible = array.getBoolean(R.styleable.AutoMaticPageGridView_auto_button_visible, true);//默认true
array.recycle();
//分页用
viewPager = new ViewPager(context);
viewPager.setLayoutParams(new LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT));
addView(viewPager);
//导航点用
radioGroup = new RadioGroup(context);
radioGroup.setOrientation(LinearLayout.HORIZONTAL);
RelativeLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
radioGroup.setLayoutParams(params);
addView(radioGroup);
//如果不显示的话就隐藏
if (!btn_isvisible) {
radioGroup.setVisibility(GONE);
}
} //设置适配器
public void setAdapter(BaseAutoAdapter baseAdapter) {
this.adapter = baseAdapter;
//计算页数
if ((adapter.getCounts() / (column * lines)) > 0) {
pages = (adapter.getCounts() / (column * lines)) + 1; //多一页
} else {
pages = adapter.getCounts();
}
//添加radioButton
addRadioButton(pages);
this.post(new Runnable() {
@Override
public void run() {
itemHeight = getMeasuredHeight() / lines;
//显示viewpager
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getContext());
viewPager.setAdapter(viewPagerAdapter);
//设置联动
initLinkAgeEvent();
}
});
} //添加RadioButton
private void addRadioButton(int pages) {
for (int i = 0; i < pages; i++) {
RadioButton radioButton = new RadioButton(getContext());
radioButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
radioButton.setPadding(5, 5, 5, 5);//间距
radioButton.setId(i);//设置Id,方便联动
radioButton.setClickable(false);
if (btn_res != 0) { //设置按钮样式
radioButton.setButtonDrawable(btn_res);
}
radioGroup.addView(radioButton);
}
} //给当前页计算数据数量
private List<View> getAdapterData(int position) {
List<View> cerrent = new ArrayList<>();
if (position == pages - 1) { //如果等于最后一页
for (int i = position * (lines * column); i < adapter.getCounts(); i++) {
cerrent.add(adapter.getItemView(i, null));
}
} else {
for (int i = position * (lines * column); i < position * (lines * column) + (lines * column); i++) {
cerrent.add(adapter.getItemView(i, null));
}
}
return cerrent;
} //ViewPager适配器
private class ViewPagerAdapter extends PagerAdapter { private Context context; public ViewPagerAdapter(Context context) {
this.context = context;
} @Override
public int getCount() {
return pages;
} @Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
CustomGridView gridView = new CustomGridView(context);
gridView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
AbsListView.LayoutParams.MATCH_PARENT));
gridView.setNumColumns(column);//设置列数
gridView.setColumnWidth(GridView.AUTO_FIT);
GridViewAdapter adapter = new GridViewAdapter(getAdapterData(position), position);
gridView.setAdapter(adapter);
container.addView(gridView);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
GridViewAdapter adapter1 = (GridViewAdapter) parent.getAdapter();
onItemClickCallBack.OnItemClicked(adapter1.currentPage * (lines * column) + position, view);
}
});
return gridView;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((GridView) object);
}
} //GridView的适配器
private class GridViewAdapter extends BaseAdapter { private List<View> views;//数据量
public int currentPage; //当前页 public GridViewAdapter(List<View> counts, int currentPage) {
this.views = counts;
this.currentPage = currentPage;
} @Override
public int getCount() {
return views.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) {
if (convertView == null) {
convertView = views.get(position);
convertView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight));
}
return convertView;
} } //自定义GridView,禁止滑动
private class CustomGridView extends GridView { public CustomGridView(Context context) {
super(context);
} public CustomGridView(Context context, AttributeSet attrs) {
super(context, attrs);
} public CustomGridView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} @TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
} @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
return true;//禁止GridView进行滑动
}
return super.dispatchTouchEvent(ev);
}
} //初始化联动联动事件
private void initLinkAgeEvent() {
//默认选中第一个
viewPager.setCurrentItem(0);
radioGroup.check(radioGroup.getChildAt(0).getId());
//滑动换页事件
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int position) {
radioGroup.check(position);
} @Override
public void onPageScrollStateChanged(int state) { }
});
} }

这个组件也有个适配器,很简单,就是定义了几个抽象方法

package custom.widget;

import android.view.View;
import android.view.ViewGroup; /**
* Created by ouhimehime on 16/5/4.
* -----适配器=------
*/
public abstract class BaseAutoAdapter { public abstract int getCounts(); //返回数据数量 public abstract Object getItem(int position); //当前Item的数据 public abstract View getItemView(int position, ViewGroup parent); //返回Item的布局 }

还自定义了一部分属性,方便使用起来好控制

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="AutoMaticPageGridView">
<!-- 行数 -->
<attr name="auto_lines" format="integer" />
<!-- 列数 -->
<attr name="auto_column" format="integer" />
<!-- button的样式 -->
<attr name="auto_button" format="reference" />
<!-- 是否显示导航点 -->
<attr name="auto_button_visible" format="boolean" />
</declare-styleable>
</resources>

-----------------------------------------------------------------------以上就是源代码了-----------------------------------------------------------------------------

下面是如何使用:(就当做一个控件来使用就可以)

①、先看布局文件XML,控件的高度是可以自己定义的

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:auto="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"> <custom.widget.AutoMaticPageGridView
android:id="@+id/automatic"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
auto:auto_button="@drawable/btn_status_style"
auto:auto_column="3"
auto:auto_lines="2" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"/> </LinearLayout>

②、再看适配器代码,适配器需要继承BaseAutoAdapter

package adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import com.newair.automaticpagedemo.R; import java.util.List; import custom.widget.BaseAutoAdapter; /**
* Created by ouhimehime on 16/5/4.
* ------------适配器------------
*/
public class MyAutoMaticPageAdapter extends BaseAutoAdapter { private Context context;
private List<Integer> myData; public MyAutoMaticPageAdapter(Context context, List<Integer> myData) {
this.context = context;
this.myData = myData;
} @Override
public int getCounts() {
return myData.size();
} @Override
public Object getItem(int position) {
return myData.get(position);
} @Override
public View getItemView(int position, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.item_layout, null); return view;
} }

③、再看主布局代码,为了方便我就随便放了放了10条数据

package com.newair.automaticpagedemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast; import java.util.ArrayList;
import java.util.List; import adapter.MyAutoMaticPageAdapter;
import custom.widget.AutoMaticPageGridView; public class MainActivity extends AppCompatActivity { private AutoMaticPageGridView automatic;
private MyAutoMaticPageAdapter adapter;
private List<Integer> myData; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
automatic = (AutoMaticPageGridView) findViewById(R.id.automatic);
myData = new ArrayList<>();
for (int i = 0; i < 10; i++) {
myData.add(i);
} adapter = new MyAutoMaticPageAdapter(this, myData);
automatic.setAdapter(adapter);
//点击事件
automatic.setOnItemClickListener(new AutoMaticPageGridView.OnItemClickCallBack() {
@Override
public void OnItemClicked(int position, Object object) {
Toast.makeText(MainActivity.this, position + "--", Toast.LENGTH_SHORT).show();
}
});
}
}

------------------------------------------------------------------------以上是如何使用----------------------------------------------------------------------------------

以上就是自己定义了一个自动分页的控件,写的不好,希望各位见谅。

Android--自定义控件---自动分页的GridView的更多相关文章

  1. Android自定义控件 开源组件SlidingMenu的项目集成

    在实际项目开发中,定制一个菜单,能让用户得到更好的用户体验,诚然菜单的样式各种各样,但是有一种菜单——滑动菜单,是被众多应用广泛使用的.关于这种滑动菜单的实现,我在前面的博文中也介绍了如何自定义去实现 ...

  2. android自定义控件---添加表情

    android自定义控件---添加表情 一.定义layout文件,图片不提供了 <?xml version="1.0" encoding="utf-8"? ...

  3. Android自定义控件之自定义ViewGroup实现标签云

    前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...

  4. Android自定义控件之自定义组合控件

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

  5. Android自定义控件之自定义属性

    前言: 上篇介绍了自定义控件的基本要求以及绘制的基本原理,本篇文章主要介绍如何给自定义控件自定义一些属性.本篇文章将继续以上篇文章自定义圆形百分比为例进行讲解.有关原理知识请参考Android自定义控 ...

  6. Android自定义控件之基本原理

    前言: 在日常的Android开发中会经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件,今天先大致了解一下自定义控件的要求和实现的基本原理. 自 ...

  7. Android自定义控件1

    概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...

  8. 一起来学习Android自定义控件1

    概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...

  9. [Xamarin.Android] 自定义控件

    [Xamarin.Android] 自定义控件 前言 软件项目开发的过程中,免不了遇到一些无法使用内建控件就能满足的客户需求,例如:时速表.折线图...等等.这时开发人员可以透过自定义控件的方式,为项 ...

随机推荐

  1. centos 7 hadoop的安装和使用

    准备工作 安装jdk 用户免密登录 安装参考文章: http://blog.csdn.net/circyo/article/details/46724335 http://www.linuxidc.c ...

  2. CDN基本工作过程

    看了一些介绍CDN的文章,感觉这篇是讲的最清楚的. 使用CDN会极大地简化网站的系统维护工作量,网站维护人员只需将网站内容注入CDN的系统,通过CDN部署在各个物理位置的服务器进行全网分发,就可以实现 ...

  3. [Java初探08]__简单学习Java类和对象

    前言 在前面的学习中,我们对面向对象的编程思想有了一个基本的了解,并且简单的了解了类和对象的定义.那么类和对象在Java语言中是如何表现的,这次,就从实际出发,学习一下一下类和对象在Java语言中的使 ...

  4. springboot 入门

    使用maven构建project项目, 配置aliyun仓库, 不赘述 springboot 版本需要: jdk1.7+, maven3.2+ , gradle2.9+ 配置文件 引入父包, 放在&l ...

  5. Charles抓包之HTTPS抓包配置

    访问我的博客 前言 由于工作中经常需要配置客户端开发人员对接接口,有时候对接地不太顺利,因此需要经常性地对公司 APP 进行抓包看请求,找出具体的原因. 在公司中开发使用的 Windows 台式电脑, ...

  6. BackgroundWorker简单实用(简便的异步操作)

    微软提供了一个快捷使用多线程的帮助类BackgroundWorker,能够快速创建一个新的线程,并能报告进度,暂停,以及在线程完成后处理别的任务. 1.BackgroundWorker类介绍 1.1. ...

  7. Ansible工作流程详解

    1:Ansible的使用者 ------>Ansible的使用者来源于多种维度,(1):CMDB(Configuration Management Database,配置管理数据库),CMDB存 ...

  8. ELK之filebeat

    1.概述 filebeat使用go语言开发,轻量级.高效.主要由两个组件构成:prospector和harvesters. Harvesters负责进行单个文件的内容收集,在运行过程中,每一个Harv ...

  9. Apriori算法进行关联分析

    设全集U = {a, b, c, d, e},其元素a,b, c, d, e称为项. 数据集: D = [ {a, b}, {b, c, d}, {d, e}, {b, c, e}, {a,b, c, ...

  10. 【learning】多项式开根详解+模板

    概述 多项式开跟是一个非常重要的知识点,许多多项式题目都要用到这一算法. 用快速数论变换,多项式求逆元和倍增法可以在$O(n log n)$的时间复杂度下求出一个$n$次多项式的开根. 前置技能 快速 ...