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

it2022-05-09  26

  由于使用系统自带的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 出来,但注意要设置它每列显示的个数。

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

转载于:https://www.cnblogs.com/TerryBlog/archive/2011/01/18/1938637.html

相关资源:数据结构—成绩单生成器

最新回复(0)