- 浏览: 1954287 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
龙宝宝吱吱:
我现在知道是在部署的项目里找,可是找不到啊,一般这个文件会在什 ...
webservice浏览器远程调用测试 -
龙宝宝吱吱:
这个webconfig文件在哪里啊,大神
webservice浏览器远程调用测试 -
yuer1218:
正在学习这块,能把源码发我一份吗,12045464@qq.co ...
Android时钟的widget【安卓进化三十七】 -
hongshanguo:
为嘛没有任务管理器的,求案例啊
近百android程序源码贡献 -
难得糊涂CN2010:
最近一个项目要用到widget,可以送下源码不?dz.bita ...
Android时钟的widget【安卓进化三十七】
由于使用系统自带的GridView 不够灵活,不能允许拖拉控件,故自己结合LinearLayout 封装的一个GridView ,通过本篇文章的阅读你可以学会如何自定义控件,如何使用组合控件,如何为自己的组合控件添加数据源和如何为自定义控件添加属性。
首先,我们要实现的效果是这样的:
上面1 2也是一个封装控件,用来为应用程序分页,具体如何实现下篇文章会提到,本篇先讲GridView。如图,这是一个标准的800*480大小的屏幕,所以设置了一页GridView 显示的应用程序数据为 三行五列,不足五列则按需显示。
按照上面的图例需求,大致上可以把GridView 画成如下的方式:
思路如下:
默认将我们的组合控件设置为Orientation 是VERTICAL。 首先一行五个,那么一行以一个Orientation 为HORIZONTAL 的线性布局包起来。然后在一行结束后,将Orientation 的线性布局添加进组合控件里面来,不足五个则按需添加进来。
实现这一效果我们需要两个类,一个类用来表示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 ;
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 每列显示的个数,属性点的代码为如下:
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 的操作,等下文再讲述。效果是这样的:
该 类的全部源码为:


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文件:
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 出来,但注意要设置它每列显示的个数。
下篇将讲述如何实现手势切屏,如何实现分页显示数据,如何实现封装分页控件。
相关推荐
Android 实现机顶盒手势、数据分页功能,本源码需要800*480分辨率的模拟器才可运行。DEMO源码内使用到的封装类,包括一个分页控件、一个列表控件GridView 、一个支持动画效果的ViewFlipper。下载此源码的朋友可以从...
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
前端分析-2023071100789
基于kinect的3D人体建模C++完整代码.cpp
搞机工具箱10.1.0.7z
GRU+informer时间序列预测(Python完整源码和数据),python代码,pytorch架构,适合各种时间序列直接预测。 适合小白,注释清楚,都能看懂。功能如下: 代码基于数据集划分为训练集测试集。 1.多变量输入,单变量输出/可改多输出 2.多时间步预测,单时间步预测 3.评价指标:R方 RMSE MAE MAPE,对比图 4.数据从excel/csv文件中读取,直接替换即可。 5.结果保存到文本中,可以后续处理。 代码带数据,注释清晰,直接一键运行即可,适合新手小白。
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
基于ANSYS LSDyna的DEM-SPH-FEM耦合模拟滑坡入水动态行为研究,基于ANSYS LSDyna的DEM-SPH-FEM耦合的滑坡入水模拟分析研究,基于ansys lsdyna的滑坡入水模拟dem-sph-fem耦合 ,基于ANSYS LSDyna; 滑坡入水模拟; DEM-SPH-FEM 耦合,基于DEM-SPH-FEM耦合的ANSYS LSDyna滑坡入水模拟
auto_gptq-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
复件 复件 建设工程可行性研究合同[示范文本].doc
13考试真题最近的t64.txt
好用我已经解决报错问题
# 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!
auto_gptq-0.4.2-cp38-cp38-win_amd64.whl
自动立体库设计方案.pptx
# 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!
# 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!
用deepseek变现实操流程,小白必看。