在使用GridView时我们知道,列数是可以通过设计时的属性来设置的,列的宽度则是根据列数和GridView的宽度计算出来的。但是有些时候我们想实现列数是动态改变的效果,即列的宽度保持某个值,列的数量是可变的,我们可通过获取屏幕宽度并除以项目宽度来处理。请看下面的代码:
1 2 3 4 5 6 7 8 9 10 11 |
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); GridView lvnote = (GridView)findViewById(R.id.gridView1); // The item width is about 200,项目宽度大概200像素 colnum = (int) (((getResources().getDisplayMetrics().widthPixels )) / 200 ); lvnote.setNumColumns(colnum); } |
但是由于不同的Android设备可能有不同的宽度,项目宽度乘以获得的列数所得到的总宽度并不能填充整个屏幕的宽度,而给用户带来不好的用户体验,甚至我们可能还需要使行高和列宽保持一定的比例,那么如何动态调整项目的宽度和高度呢?
我们此处是通过写一个自己的Adapter类,并改写其中的getView函数来实现的,getView是用来返回某个GridView项的部局的函数,我们在此处手动生成需要的view并设置此view的宽度和高度,最后将此view返回。
注:使用此方法时,项目中的内容可能也需要手动去填充,请再研究
相关文件及代码如下:
主窗体只有一个GridView,部局文件代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <GridView android:id="@+id/gridView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:gravity="center_horizontal" android:numColumns="3" > </GridView> </RelativeLayout> |
GridView项所使用的部局文件只有一个TextView,命名为note_item,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/tvNote" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> </LinearLayout> |
Activity类的实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
package com.example.apptest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.GridView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; public class MainActivity extends Activity { GridView lvnote; ArrayList<HashMap<String, String>> mynotelist = new ArrayList<HashMap<String,String>>(); int colnum = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvnote = (GridView)findViewById(R.id.gridView1); // The item width is about 200,项目宽度大概200像素 colnum = (int) (((getResources().getDisplayMetrics().widthPixels )) / 200 ); lvnote.setNumColumns(colnum); HashMap<String, String> mapitem1 = new HashMap<String, String>(); mapitem1.put("note", "Hello1..."); mapitem1.put("noteid", "1"); mynotelist.add(mapitem1); HashMap<String, String> mapitem2 = new HashMap<String, String>(); mapitem2.put("note", "Hello2..."); mapitem2.put("noteid", "2"); mynotelist.add(mapitem2); HashMap<String, String> mapitem3 = new HashMap<String, String>(); mapitem3.put("note", "Hello3..."); mapitem3.put("noteid", "3"); mynotelist.add(mapitem3); HashMap<String, String> mapitem4 = new HashMap<String, String>(); mapitem4.put("note", "Hello4..."); mapitem4.put("noteid", "4"); mynotelist.add(mapitem4); HashMap<String, String> mapitem5 = new HashMap<String, String>(); mapitem5.put("note", "Hello5..."); mapitem5.put("noteid", "5"); mynotelist.add(mapitem5); HashMap<String, String> mapitem6 = new HashMap<String, String>(); mapitem6.put("note", "Hello6..."); mapitem6.put("noteid", "6"); mynotelist.add(mapitem6); NoteAdapter adapter = new NoteAdapter(this, mynotelist, R.layout.note_item, new String[]{"note"}, new int[]{R.id.tvNote}); lvnote.setAdapter(adapter); } public class NoteAdapter extends SimpleAdapter{ Context context = null; @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub // Inflate the note_item layout manually, and treat it as the item view // 重新填充note_item部局,并把它作为项的view返回 convertView = LayoutInflater.from(context).inflate(R.layout.note_item, null); HashMap<String, String> theMap = (HashMap<String, String>)getItem(position); TextView txtNote = (TextView)convertView.findViewById(R.id.tvNote); txtNote.setText(theMap.get("note").toString()); // Calculate the item width by the column number to let total width fill the screen width // 根据列数计算项目宽度,以使总宽度尽量填充屏幕 int itemWidth = (int)(getResources().getDisplayMetrics().widthPixels - colnum * 10) / colnum; // Calculate the height by your scale rate, I just use itemWidth here // 下面根据比例计算您的item的高度,此处只是使用itemWidth int itemHeight = itemWidth; AbsListView.LayoutParams param = new AbsListView.LayoutParams( itemWidth, itemHeight); convertView.setLayoutParams(param); return convertView; } public NoteAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) { super(context, data, resource, from, to); this.context = context; } } } |