Android--自定义控件---自动分页的GridView
最近,根据项目需求,需要一个能够自动分页的导航,所以便自定义了一个自动分页的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的更多相关文章
- Android自定义控件 开源组件SlidingMenu的项目集成
在实际项目开发中,定制一个菜单,能让用户得到更好的用户体验,诚然菜单的样式各种各样,但是有一种菜单——滑动菜单,是被众多应用广泛使用的.关于这种滑动菜单的实现,我在前面的博文中也介绍了如何自定义去实现 ...
- android自定义控件---添加表情
android自定义控件---添加表情 一.定义layout文件,图片不提供了 <?xml version="1.0" encoding="utf-8"? ...
- Android自定义控件之自定义ViewGroup实现标签云
前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...
- Android自定义控件之自定义组合控件
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
- Android自定义控件之自定义属性
前言: 上篇介绍了自定义控件的基本要求以及绘制的基本原理,本篇文章主要介绍如何给自定义控件自定义一些属性.本篇文章将继续以上篇文章自定义圆形百分比为例进行讲解.有关原理知识请参考Android自定义控 ...
- Android自定义控件之基本原理
前言: 在日常的Android开发中会经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件,今天先大致了解一下自定义控件的要求和实现的基本原理. 自 ...
- Android自定义控件1
概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...
- 一起来学习Android自定义控件1
概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...
- [Xamarin.Android] 自定义控件
[Xamarin.Android] 自定义控件 前言 软件项目开发的过程中,免不了遇到一些无法使用内建控件就能满足的客户需求,例如:时速表.折线图...等等.这时开发人员可以透过自定义控件的方式,为项 ...
随机推荐
- (转)kafka实战教学
转载自:https://www.cnblogs.com/hei12138/p/7805475.html Apache kafka 工作原理介绍-----https://www.ibm.com/deve ...
- 多线程之CountDownLatch和CyclicBarriar使用
CountDownLatch和CyclicBarriar是java.util.concurrent包下面提供的多线程同步工具,两者有点相似,相当于计数器,但是用处还是有区别的. CountDownLa ...
- spring jpa : 多条件查询
https://www.cnblogs.com/Donnnnnn/p/6277872.html 方式一: 第一步:EmpAccNumService package com.payease.scford ...
- linux下的进程(孤儿进程、僵尸进程)
linux提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息,就可以得到.这种机制就是:在每个进程退出的时候,内核释放该进程所有的资源,包括打开文件,占用的内存等.但是仍然为其保留一定的信息 ...
- docker网络之bridge
建议阅读本文章之前了解一下文章,本文不作bridge的基本介绍 https://blog.csdn.net/u014027051/article/details/53908878/ http://wi ...
- Leetcode 759. Employee Free Time
思路:区域覆盖问题.一个自然的想法是将每个员工的工作时间段看做一个木棒,每个木棒的长度就是这个时间段的时长.然后按照木棒的起始位置升序排列,接着由低位置向高位置一个木棒一个木棒的看过去.如果当前木棒的 ...
- Android so 文件进阶<二> 从dlsym()源码看android 动态链接过程
0x00 前言 这篇文章其实是我之前学习elf文件关于符号表的学习笔记,网上也有很多关于符号表的文章,怎么说呢,感觉像是在翻译elf文件格式的文档一样,千篇一律,因此把自己的学习笔记分享出来.dls ...
- INTEST/EXTEST SCAN
INTEST scan指的是对IP 内部的scan cell的扫描测试,针对IP内部的flip-flop进行shift/capture的操作.和INTEST SCAN 对应的就是EXTEST SCAN ...
- <Think Python>中统计文献单词的处理代码
def process_line(line, hist): """Adds the words in the line to the histogram. Modi ...
- JavaScript核心基础语法
1 什么是JavaScript? 是一种嵌入在网页中的程序段. 是一种解释型语言,被浏览器解释执行. 由Netscape发明,ECMA(欧洲计算机制造商协会)将其标准化. JavaScript借用了J ...