首页 > 其他分享 >Android GridView控件自定义

Android GridView控件自定义

时间:2022-10-06 11:33:23浏览次数:79  
标签:控件 layout 自定义 int cell new Android public android


虽然​​Android​​​已自带了GridView,但是,却不够灵活,同时也不能自由添加控件,因此,本人通过需要进一步封装,来实现​​Android自定义GridView控件​​,达到自己需要的效果。


我们看一下最终所需要的效果图:


Android GridView控件自定义_interface

说明:

上图:这里先省去分页,只讲:​​Android GridView​​ 控件实现自定义。

按照上面的图例需求,大致上可以把​​Android GridView​​ 画成如下的方式:

Android GridView控件自定义_object_02

思路如下:

   默认将我们的组合控件设置为Orientation 是VERTICAL。 首先一行五个,那么一行以一个Orientation 为HORIZONTAL 的线性布局包起来。然后在一行结束后,将Orientation 的线性布局添加进组合控件里面来,不足五个则按需添加进来。

  实现这一效果我们需要两个类,一个类用来表示​​Android GridView​​ 的行,这里我们起名为TableRow,代码如下:

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;

}

}

  另外一个类用来表示GridView 每行的列个,这里我们取名为TableCell,代码如下:

static
public
class TableCell {

private Object value;


public TableCell(Object value) {

this.value = value;

}


public Object getValue() {

return value;

}

}

  并且我们还需要为GridView 设置一个外部可添加数据的方法,代码如下:

public
void setAdapter(AppsAdapter appsAdapter) {

this.adapter = appsAdapter;

this.setOrientation(LinearLayout.VERTICAL);

bindView();

}

其中,AppsAdapter 是一个自定义的BaseAdapter ,代码很简单,这里就不列出来了。关键的还是要看bindView ,这个方法是本篇GridView 显示数据的核心方法,代码如下:

void bindView() {

removeAllViews();

int count = adapter.getCount();

TableCell[] cell =
null;

int j =
0;

LinearLayout layout;

tableRowsList =
new ArrayList<HashMap<String, Object>>();

for (
int i =
0; i < count; i++) {

j++;

final
int position = i;

if (j > getColumnCount() || i ==
0) {

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 = -
1;

checkColumnID = -
1;

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 -
1] =
new TableCell(view);

if (j == getColumnCount()) {

lastRowCount = j;

j =
0;

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);


}
else
if (i >= count -
1 && j >
0) {

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 每列显示的个数,属性点的代码为如下:

public gridViewExt(Context context, AttributeSet attrs) {

super(context, attrs);

int resouceID = -
1;

TypedArray typedArray = context.obtainStyledAttributes(attrs,

R.styleable.GridViewExt);

int N = typedArray.getIndexCount();

for (
int i =
0; i < N; i++) {

int attr = typedArray.getIndex(i);

switch (attr) {

case R.styleable.GridViewExt_ColumnCount:

resouceID = typedArray.getInt(

R.styleable.GridViewExt_ColumnCount,
0);

setColumnCount(resouceID);

break;


}

}

typedArray.recycle();

}


当然,你必须在res 创建属性xml ,这里不多讲,可以去我博客看看如何为 ​​ View 添加属性​​ 。

还有,还必须实现它的支持键盘的上下左右的焦点,下面的代码将会提供该功能,但还必须配合Activity 的操作,等下文再讲述。效果是这样的:

Android GridView控件自定义_object_03

全部源码为:


package com.yaomei.widget;


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;

int checkRowID = -
1;
//
选中行的下标


int checkColumnID = -
1;
//
选中列的下标


int lastRowCount = -
1;
//
最后一行的总数


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);

int resouceID = -
1;

TypedArray typedArray = context.obtainStyledAttributes(attrs,

R.styleable.GridViewExt);

int N = typedArray.getIndexCount();

for (
int i =
0; i < N; i++) {

int attr = typedArray.getIndex(i);

switch (attr) {

case R.styleable.GridViewExt_ColumnCount:

resouceID = typedArray.getInt(

R.styleable.GridViewExt_ColumnCount,
0);

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;

int j =
0;

LinearLayout layout;

tableRowsList =
new ArrayList<HashMap<String, Object>>();

for (
int i =
0; i < count; i++) {

j++;

final
int position = i;

if (j > getColumnCount() || i ==
0) {

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 = -
1;

checkColumnID = -
1;

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 -
1] =
new TableCell(view);

if (j == getColumnCount()) {

lastRowCount = j;

j =
0;

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);


}
else
if (i >= count -
1 && j >
0) {

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
params =
new LinearLayout.LayoutParams(
130,

110);

layout.setGravity(Gravity.LEFT);


layout.setOrientation(LinearLayout.HORIZONTAL);

for (
int k =
0; 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 =
60;

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;

if (name[
0].toString().equals(
"
com.android.contacts
")) {

if (name[
1].toString().equals(

"
com.android.contacts.DialtactsActivity
")) {

intent =
new Intent(Intent.ACTION_DIAL);

}

if (name[
1].toString().equals(

"
com.android.contacts.DialtactsContactsEntryActivity
")) {

intent =
new Intent(Intent.ACTION_CALL_BUTTON);

}

}
else {

intent = getContext().getPackageManager()

.getLaunchIntentForPackage(name[
0].toString());

}

context.startActivity(intent);


}


/*
*
* 改变图片状态
*
* @param v
* @param list

*/

private
void changeImageState(View v, List<HashMap<String, Object>> list) {

int size = list.size();

for (
int i =
0; 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() {

if (checkColumnID != -
1 && checkRowID != -
1) {

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文件:


<
LinearLayout
android:orientation
="vertical"

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控件​​自定义吧。

标签:控件,layout,自定义,int,cell,new,Android,public,android
From: https://blog.51cto.com/jdsjlzx/5733507

相关文章

  • Android实现渐显按钮的左右滑动效果
    本示例演示在Android中实现带渐显按钮的左右滑动效果。关于滑动效果,在我的上一篇博文中提到过,有兴趣的朋友可以访问如果大家想实现带指引效果的左右滑动,请访问博先看下......
  • Android闪屏示例程序
     用过手机QQ的基本上都知道,刚启动程序时候会在一个界面停留一会,按任意键的就直接跳过,这就是所谓的闪屏。那么,在Android中怎样实现这样的效果呢? 1、新建一个Android项目,命......
  • Android实现图片倒影效果
    ​​android倒影实现抖动的镜面效果​​​​http://clareshao.iteye.com/blog/1419695​​android中的gallery的一个样式,具有倒影效果。左右滑动也不错。​​http://down......
  • Android开发--构建项目安装包APK(debug版)
    1.build→BuildAPK(s),点击即可构建2.点击日志可以查看构建情况3.点击locate即可进入debug文件夹4.也可以在构建完成后直接按照路径找到debug文件夹其中apk文件即所需安装......
  • Vue.js框架:自定义组件全局挂载,避免每个用到的页面需要重复导入问题
    一、打包组件可以建立一个打包工具类,将所有的需要全局挂载的自定义组件进行打包封装,避免main.js过于杂乱。importgbInputfrom'../components/gbInput/gbInput'/......
  • Android类加载流程
    背景由于前前前阵子写了个壳,得去了解类的加载流程,当时记了一些潦草的笔记。这几天把这些东西简单梳理了一下,本文分析的代码基于Android8.1.0源码。流程分析从loadClass......
  • Vue强大的插件功能,你也可以自定义实现想要功能!
    插件定义插件通常用来为Vue添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:添加全局方法或者property。如:vue-custom-element添加全局资源:指令/过滤器/过......
  • 大聪明教你学Java | Spring Boot 使用自定义注解实现防止表单重复提交
    前言这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战表单重复提交是在多用户的Web应用中最常见且带来麻烦最多的一个问题。有很多的应用场景都会遇到......
  • 【WXSC】python自定义包
    沉淀自己的一些脚本和算法,托管在github或gitee上;使用的时候,直接pip安装即可,不用每次都去拷贝源码,修改源码1.构建一个本地包setup.py文件必须MANIFEST.in文件:可......
  • 【C语言_15】自定义函数和math库函数详解篇!
    一.函数的概念1.什么是函数?函数就是一段封装好的,可以重复使用的代码,它使得我们的程序更加模块化,不需要编写大量重复的代码。函数可以提前保存起来,并给它起一个独一无二的名......