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] 自定义控件 前言 软件项目开发的过程中,免不了遇到一些无法使用内建控件就能满足的客户需求,例如:时速表.折线图...等等.这时开发人员可以透过自定义控件的方式,为项 ...
随机推荐
- Android的Fragment的第一种声明方式
Android的Frangment的第一种声明方式 实际效果图如下: 项目结构图如下: fragment1: package com.demo.fragementfirst; import andro ...
- ASP.NET WebAPI Bearer Authorization
使用VS2015新建一个WebApi项目. 关键的配置在Startup.Auth.cs里 public partial class Startup { public static OAuthAutho ...
- 【JAVA】序列化
好处有2: 实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里). 利用序列化实现远程通信,即在网络上传送对象的字节序列. 序列化ID的作用: 简单来说,Java的序列化机制 ...
- GO入门——5. 函数
1 函数 Go 函数 不支持 嵌套.重载和默认参数 定义函数使用关键字 func,且左大括号不能另起一行 函数也可以作为一种类型使用 无需声明原型 不定长度变参 func A(a string,c . ...
- 你真的理解编码吗?unicode,utf8,utf16详解
背景 前两天在网上看到一篇关于编码的讨论,仔细学习了一下unicode,utf8,utf16的定义.这篇博客旨在让读者真正理解他们是什么. 什么是编码 在阅读本文之前建议读者先去阅读这篇文章:http ...
- CORS实践
$.ajax("http://yafbox.18touch.com/", { type: "POST", data: {id:id,v:v}, //header ...
- ng-app与ng-app='myApp'的区别
ng-app与ng-app=""是一样的,都是没定义应用名的,例如 <div ng-app="" ng-init="firstName='ech ...
- core Animation之CATransition(转场动画)
用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点 UINavigationController就是通过CATransition实现了将控制器的视图 ...
- Net Core 中间件实现修改Action的接收参数及返回值
新一个WebApi项目(Net Core 2.1) 新建InputOutputAlterMiddleware类,修改命名空间为Microsoft.AspNetCore.Builder(不修改也没关系, ...
- SQL语句大全从基础到熟练(不含数据库高端操作)日常用户 三、
前言 昨天晚上回家忘记带钥匙导致在楼下站街三小时,鬼天气热的不要不要的然后我就在车里坐了会之后就.....zzZZ,哈哈睡的挺香的毕竟累了一天了 上两篇文章都是介绍的语法语句,本篇文章介绍下函数的使用 ...