您当前的位置: 首页 > 

xiangzhihong8

暂无认证

  • 3浏览

    0关注

    1324博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

自定义gradview

xiangzhihong8 发布时间:2014-10-31 20:25:51 ,浏览量:3

http://blog.csdn.net/jdsjlzx/article/details/7525724

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

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

说明:

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

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

思路如下:

   默认将我们的组合控件设置为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(); 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 map =  new HashMap(); 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 map =  new HashMap(); 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 的操作,等下文再讲述。效果是这样的:

全部源码为:

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 tableRowsList; private List app =  new ArrayList(); 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(); 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 map =  new HashMap(); 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 map =  new HashMap(); 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 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 map =  new HashMap(); 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文件:

完成这一系列的编写后,你就可以在xml直接写或者在JAVA文件里面new 出来,但注意要设置它每列显示的个数。

如何,看到这里,是不是觉得自定义的GridView很强大呢?大也自己DIY一下Android GridView控件自定义吧

关注
打赏
1482932726
查看更多评论
立即登录/注册

微信扫码登录

0.0441s