在使用GridView時我們知道,列數是可以通過設計時的屬性來設置的,列的寬度則是根據列數和GridView的寬度計算出來的。但是有些時候我們想實現列數是動態改變的效果,即列的寬度保持某個值,列的數量是可變的,我們可通過獲取屏幕寬度並除以項目寬度來處理。請看下面的代碼:
@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,部局文件代碼:
<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,代碼如下:
<?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類的實現代碼如下:
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; } } }