`
jandroid
  • 浏览: 1954287 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Android 分享机顶盒项目的封装类《GridView》

阅读更多

由于使用系统自带的GridView 不够灵活,不能允许拖拉控件,故自己结合LinearLayout 封装的一个GridView ,通过本篇文章的阅读你可以学会如何自定义控件,如何使用组合控件,如何为自己的组合控件添加数据源和如何为自定义控件添加属性。

  首先,我们要实现的效果是这样的:

  上面1 2也是一个封装控件,用来为应用程序分页,具体如何实现下篇文章会提到,本篇先讲GridView。如图,这是一个标准的800*480大小的屏幕,所以设置了一页GridView 显示的应用程序数据为 三行五列,不足五列则按需显示。

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

 

  思路如下:

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

  实现这一效果我们需要两个类,一个类用来表示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 的操作,等下文再讲述。效果是这样的:

该 类的全部源码为:

 

GridViewExt
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 出来,但注意要设置它每列显示的个数。

下篇将讲述如何实现手势切屏,如何实现分页显示数据,如何实现封装分页控件。

分享到:
评论

相关推荐

    Android 实现机顶盒手势、数据分页功能.rar

    Android 实现机顶盒手势、数据分页功能,本源码需要800*480分辨率的模拟器才可运行。DEMO源码内使用到的封装类,包括一个分页控件、一个列表控件GridView 、一个支持动画效果的ViewFlipper。下载此源码的朋友可以从...

    避开10大常见坑:DeepSeekAPI集成中的错误处理与调试指南.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    前端分析-2023071100789

    前端分析-2023071100789

    基于kinect的3D人体建模C++完整代码.cpp

    基于kinect的3D人体建模C++完整代码.cpp

    搞机工具箱10.1.0.7z

    搞机工具箱10.1.0.7z

    GRU+informer时间序列预测(Python完整源码和数据)

    GRU+informer时间序列预测(Python完整源码和数据),python代码,pytorch架构,适合各种时间序列直接预测。 适合小白,注释清楚,都能看懂。功能如下: 代码基于数据集划分为训练集测试集。 1.多变量输入,单变量输出/可改多输出 2.多时间步预测,单时间步预测 3.评价指标:R方 RMSE MAE MAPE,对比图 4.数据从excel/csv文件中读取,直接替换即可。 5.结果保存到文本中,可以后续处理。 代码带数据,注释清晰,直接一键运行即可,适合新手小白。

    性价比革命:DeepSeekAPI成本仅为GPT-4的3%的技术揭秘.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    基于ANSYS LSDyna的DEM-SPH-FEM耦合模拟滑坡入水动态行为研究,基于ANSYS LSDyna的DEM-SPH-FEM耦合的滑坡入水模拟分析研究,基于ansys lsdyna的滑坡入水

    基于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

    auto_gptq-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

    复件 复件 建设工程可行性研究合同[示范文本].doc

    复件 复件 建设工程可行性研究合同[示范文本].doc

    13考试真题最近的t64.txt

    13考试真题最近的t64.txt

    Microsoft Visual C++ 2005 SP1 Redistributable PackageX86

    好用我已经解决报错问题

    嵌入式开发入门:用C语言点亮LED灯的全栈开发指南.pdf

    # 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!

    auto_gptq-0.4.2-cp38-cp38-win_amd64.whl

    auto_gptq-0.4.2-cp38-cp38-win_amd64.whl

    自动立体库设计方案.pptx

    自动立体库设计方案.pptx

    手把手教你用C语言实现贪吃蛇游戏:从算法设计到图形渲染.pdf

    # 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!

    性能对决:DeepSeek-V3与ChatGPTAPI在数学推理场景的基准测试.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    从零到一:手把手教你用Python调用DeepSeekAPI的完整指南.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    为什么你的switch总出bug?90%新手不知道的break语句隐藏规则.pdf

    # 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!

    用deepseek变现实操流程

    用deepseek变现实操流程,小白必看。

Global site tag (gtag.js) - Google Analytics