自定义gradview
http://blog.csdn.net/jdsjlzx/article/details/7525724
虽然Android已自带了GridView,但是,却不够灵活,同时也不能自由添加控件,因此,本人通过需要进一步封装,来实现Android自定义GridView控件,达到自己需要的效果。
我们看一下最终所需要的效果图:
说明:
上图:这里先省去分页,只讲:Android GridView 控件实现自定义。
按照上面的图例需求,大致上可以把Android GridView 画成如下的方式:
思路如下:
默认将我们的组合控件设置为Orientation 是VERTICAL。 首先一行五个,那么一行以一个Orientation 为HORIZONTAL 的线性布局包起来。然后在一行结束后,将Orientation 的线性布局添加进组合控件里面来,不足五个则按需添加进来。
实现这一效果我们需要两个类,一个类用来表示Android GridView 的行,这里我们起名为TableRow,代码如下:
private TableCell[] cell;
public TableRow(TableCell[] cell) {
this.cell = cell;
}
public int getSize() {
return cell.length;
}
public TableCell getCellValue(int index) {
if (index >= getSize()) {
return null;
}
return cell[index];
}
public int getCellCount() {
return cell.length;
}
public int getLastCellCount() {
return lastRowCount;
}
}
另外一个类用来表示GridView 每行的列个,这里我们取名为TableCell,代码如下:
private Object value;
public TableCell(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
}
并且我们还需要为GridView 设置一个外部可添加数据的方法,代码如下:
this.adapter = appsAdapter;
this.setOrientation(LinearLayout.VERTICAL);
bindView();
}
其中,AppsAdapter 是一个自定义的BaseAdapter ,代码很简单,这里就不列出来了。关键的还是要看bindView ,这个方法是本篇GridView 显示数据的核心方法,代码如下:
removeAllViews();
int count = adapter.getCount();
TableCell[] cell = null;
;
LinearLayout layout;
tableRowsList = new ArrayList<HashMap<String, Object>>();
; i < count; i++) {
j++;
final int position = i;
) {
cell = new TableCell[getColumnCount()];
}
final View view = adapter.getView(i, null, null);
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
unCheckPressed();
checkRowID = -;
checkColumnID = -;
if (onItemClickEvent != null) {
onItemClickEvent.onItemClick(position, event, view);
}
return false;
}
});
view.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (onLongPress != null) {
onLongPress.onLongPress(v);
}
return true;
}
});
cell[j - ] = new TableCell(view);
if (j == getColumnCount()) {
lastRowCount = j;
j = ;
HashMap<String, Object> map = new HashMap<String, Object>();
TableRow tr = new TableRow(cell);
map.put("tableRow", tr);
tableRowsList.add(map);
layout = new LinearLayout(getContext());
addLayout(layout, cell, tr.getSize(), tr);
} && j > ) {
lastRowCount = j;
HashMap<String, Object> map = new HashMap<String, Object>();
TableRow tr = new TableRow(cell);
map.put("tableRow", tr);
tableRowsList.add(map);
layout = new LinearLayout(getContext());
addLayout(layout, cell, j, tr);
}
}
}
getColumnCount()是一个属性,表示可以从xml或者从代码动态改变GridView 每列显示的个数,属性点的代码为如下:
super(context, attrs);
;
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.GridViewExt);
int N = typedArray.getIndexCount();
; i < N; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.GridViewExt_ColumnCount:
resouceID = typedArray.getInt(
R.styleable.GridViewExt_ColumnCount, );
setColumnCount(resouceID);
break;
}
}
typedArray.recycle();
}
当然,你必须在res 创建属性xml ,这里不多讲,可以去我博客看看如何为 View 添加属性 。
还有,还必须实现它的支持键盘的上下左右的焦点,下面的代码将会提供该功能,但还必须配合Activity 的操作,等下文再讲述。效果是这样的:
全部源码为:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.yaomei.activity.adapter.AppsAdapter;
import com.yaomei.activity.info.R;
public class gridViewExt extends LinearLayout {
public List<HashMap<String, Object>> tableRowsList;
private List<HashMap<String, Object>> app = new ArrayList<HashMap<String, Object>>();
private AppsAdapter adapter;
onItemClickListener onItemClickEvent;
onLongPressExt onLongPress;
; // 选中行的下标
; // 选中列的下标
; // 最后一行的总数
private int ColumnCount; // 每列的总数
public void setColumnCount(int count) {
this.ColumnCount = count;
}
public int getColumnCount() {
return ColumnCount;
}
public interface onItemClickListener {
public boolean onItemClick(int position, MotionEvent event, View view);
}
public interface onLongPressExt {
public boolean onLongPress(View view);
}
public gridViewExt(Context context) {
this(context, null);
// TODO Auto-generated constructor stub
}
public gridViewExt(Context context, AttributeSet attrs) {
super(context, attrs);
;
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.GridViewExt);
int N = typedArray.getIndexCount();
; i < N; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.GridViewExt_ColumnCount:
resouceID = typedArray.getInt(
R.styleable.GridViewExt_ColumnCount, );
setColumnCount(resouceID);
break;
}
}
typedArray.recycle();
}
public void setOnItemClickListener(onItemClickListener click) {
this.onItemClickEvent = click;
}
public void setOnLongPressListener(onLongPressExt longPress) {
this.onLongPress = longPress;
}
public void NotifyDataChange() {
removeAllViews();
}
void bindView() {
removeAllViews();
int count = adapter.getCount();
TableCell[] cell = null;
;
LinearLayout layout;
tableRowsList = new ArrayList<HashMap<String, Object>>();
; i < count; i++) {
j++;
final int position = i;
) {
cell = new TableCell[getColumnCount()];
}
final View view = adapter.getView(i, null, null);
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
unCheckPressed();
checkRowID = -;
checkColumnID = -;
if (onItemClickEvent != null) {
onItemClickEvent.onItemClick(position, event, view);
}
return false;
}
});
view.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (onLongPress != null) {
onLongPress.onLongPress(v);
}
return true;
}
});
cell[j - ] = new TableCell(view);
if (j == getColumnCount()) {
lastRowCount = j;
j = ;
HashMap<String, Object> map = new HashMap<String, Object>();
TableRow tr = new TableRow(cell);
map.put("tableRow", tr);
tableRowsList.add(map);
layout = new LinearLayout(getContext());
addLayout(layout, cell, tr.getSize(), tr);
} && j > ) {
lastRowCount = j;
HashMap<String, Object> map = new HashMap<String, Object>();
TableRow tr = new TableRow(cell);
map.put("tableRow", tr);
tableRowsList.add(map);
layout = new LinearLayout(getContext());
addLayout(layout, cell, j, tr);
}
}
}
private void addLayout(LinearLayout layout, TableCell[] cell, int size,
TableRow tr) {
LinearLayout.LayoutParams ,
);
layout.setGravity(Gravity.LEFT);
layout.setOrientation(LinearLayout.HORIZONTAL);
; k < size; k++) {
View remoteView = (View) tr.getCellValue(k).getValue();
layout.addView(remoteView, k, params);
}
LinearLayout.LayoutParams firstParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
firstParams.leftMargin = ;
addView(layout, firstParams);
}
public void setAdapter(AppsAdapter appsAdapter) {
this.adapter = appsAdapter;
this.setOrientation(LinearLayout.VERTICAL);
bindView();
}
public void checkPressed(int tableRowId, int tableRowColumnId) {
ViewGroup view = (ViewGroup) this.getChildAt(tableRowId);
checkColumnID = tableRowColumnId;
checkRowID = tableRowId;
changeImageState(view.getChildAt(tableRowColumnId), app);
}
public void onClick(int tableRowId, int tableRowColumnId, Context context) {
LinearLayout view = (LinearLayout) ((ViewGroup) this
.getChildAt(tableRowId)).getChildAt(tableRowColumnId);
TextView tv = (TextView) view.findViewById(R.id.folder);
final String[] name = tv.getText().toString().split("-");
Intent intent = null;
].toString().equals("com.android.contacts"))
{
].toString().equals(
"com.android.contacts.DialtactsActivity")) {
intent = new Intent(Intent.ACTION_DIAL);
}
].toString().equals(
"com.android.contacts.DialtactsContactsEntryActivity")) {
intent = new Intent(Intent.ACTION_CALL_BUTTON);
}
} else {
intent = getContext().getPackageManager()
.getLaunchIntentForPackage(name[].toString());
}
context.startActivity(intent);
}
/**
* 改变图片状态
*
* @param v
* @param list
*/
private void changeImageState(View v, List<HashMap<String, Object>> list) {
int size = list.size();
; i < size; i++) {
View view = (View) list.get(i).get("touch");
view.setPressed(false);
list.remove(i);
}
v.setPressed(true);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("touch", v);
list.add(map);
}
public void unCheckPressed() {
&& checkRowID != -) {
ViewGroup view = (ViewGroup) this.getChildAt(checkRowID);
view.getChildAt(checkColumnID).setPressed(false);
}
}
public class TableRow {
private TableCell[] cell;
public TableRow(TableCell[] cell) {
this.cell = cell;
}
public int getSize() {
return cell.length;
}
public TableCell getCellValue(int index) {
if (index >= getSize()) {
return null;
}
return cell[index];
}
public int getCellCount() {
return cell.length;
}
public int getLastCellCount() {
return lastRowCount;
}
}
static public class TableCell {
private Object value;
public TableCell(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
}
}
每行显示的LAYOUT文件:
android:background="@drawable/lessbtn" android:gravity="center"
android:layout_width="fill_parent" android:id="@+id/grid_layout"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView android:id="@+id/btn_appicon"
android:layout_width="55dip" android:layout_height="55dip"></ImageView>
<TextView android:id="@+id/tv_name" android:layout_width="wrap_content"
android:textColor="#030303" android:layout_height="wrap_content"></TextView>
<TextView android:id="@+id/folder" android:layout_width="wrap_content"
android:visibility="invisible" android:layout_height="wrap_content"></TextView>
</LinearLayout>
完成这一系列的编写后,你就可以在xml直接写或者在JAVA文件里面new 出来,但注意要设置它每列显示的个数。
如何,看到这里,是不是觉得自定义的GridView很强大呢?大也自己DIY一下Android GridView控件自定义吧
自定义gradview的更多相关文章
- 自定义ListView 、GradView 重写onMeasure方法让其正确显示
1 继承原始的 2 重写onMeasure方法 @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpe ...
- 关于Unity3D自定义编辑器的学习
被人物编辑器折腾了一个月,最终还是交了点成品上去(还要很多优化都还么做). 刚接手这项工作时觉得没概念,没想法,不知道.后来就去看<<Unity5.X从入门到精通>>中有关于 ...
- 一起学微软Power BI系列-使用技巧(5)自定义PowerBI时间日期表
1.日期函数表作用 经常使用Excel或者PowerBI,Power Pivot做报表,时间日期是一个重要的纬度,加上做一些钻取,时间日期函数表不可避免.所以今天就给大家分享一个自定义的做日期表的方法 ...
- JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...
- ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单
前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...
- ASP.NET Aries 入门开发教程5:自定义列表页工具栏区
前言: 抓紧时间,继续写教程,因为发现用户期待的内容,都在业务处理那一块. 不得不继续勤劳了. 这节主要介绍工具栏区的玩法. 工具栏的默认介绍: 工具栏默认包括5个按钮,根据不同的权限决定显示: 添加 ...
- UWP中实现自定义标题栏
UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...
- JavaScript 自定义对象
在Js中,除了Array.Date.Number等内置对象外,开发者可以通过Js代码创建自己的对象. 目录 1. 对象特性:描述对象的特性 2. 创建对象方式:对象直接量.new 构造函数.Objec ...
- 【WCF】自定义错误处理(IErrorHandler接口的用法)
当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...
随机推荐
- 计蒜客NOIP模拟赛(3)D1T3 任性的国王
X 国的地图可以被看作一个两行 nn 列的网格状图.现在 X 国需要修建铁路,然而该国的国王非常小气,他只想保证位于某两列之间的所有城市互相可以到达就行了,在此基础上,他希望所花费的代价最小. 铁路可 ...
- 洛谷P3164 [CQOI2014]和谐矩阵
高斯消元,可以直接消的 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...
- ●BZOJ 1531 [POI2005]Bank notes
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1531 题解: 单调队列优化多重背包DP (弱弱的我今天总算是把这个坑给填了...) 令V[i ...
- 网络基础-再议TCP
以前只是知道3次握手和4次挥手,但是对于其在连接和断开时的各个状态却不是很懂,今天就来看一下握手和挥手时的状态转换图: 1.三次握手和四次挥手时的状态转换图: 实线表示应用程序: 应用层首先发SYN的 ...
- POJ 3294 n个串中至少一半的串共享的最长公共子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 12484 Accepted: 3502 Descr ...
- bzoj 1217: [HNOI2003]消防局的设立
Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了 ...
- JFinal实现伪静态
JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有优势的同时再拥有ru ...
- 基于SSM框架实现简单的登录注册
一.环境配置 工程目录 在pom.xml添加依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=& ...
- Linux 下 HTTP连接超时
将项目部署到现场环境,HTTP请求莫名奇妙的连接超时,通过抓包定位了问题,是请求的IP被禁止掉.其中用到了抓包,将记录记录于此. tcpdump host 120.197.89.51 -i any - ...
- struts框架从.jsp页面直接访问action
<%@ page language="java" pageEncoding="UTF-8"%><%String path = request. ...