高级控件——列表类视图——网格视图GridView
=======================================================================================
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="拉伸模式:" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_stretch" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="left|center" android:spinnerMode="dialog" /> </LinearLayout> <GridView android:id="@+id/gv_planet" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#00ffff" android:horizontalSpacing="3dp" android:verticalSpacing="3dp" android:numColumns="2" android:stretchMode="columnWidth" /> </LinearLayout>
item_grid:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:orientation="vertical"> <!-- 这是显示行星名称的文本视图 --> <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textColor="@color/black" android:textSize="20sp" /> <!-- 这是显示行星图片的图像视图 --> <ImageView android:id="@+id/iv_icon" android:layout_width="match_parent" android:layout_height="100dp" android:scaleType="fitCenter" /> <!-- 这是显示行星描述的文本视图 --> <TextView android:id="@+id/tv_desc" android:layout_width="match_parent" android:layout_height="70dp" android:gravity="left|top" android:textColor="@color/black" android:textSize="13sp" /> </LinearLayout>
Planet
package com.example.myapplication; import java.util.ArrayList; import java.util.List; public class Planet { public int image; // 行星图标 public String name; // 行星名称 public String desc; // 行星描述 public Planet(int image, String name, String desc) { this.image = image; this.name = name; this.desc = desc; } private static int[] iconArray = {R.drawable.shuixing, R.drawable.jinxing, R.drawable.diqiu, R.drawable.huoxing, R.drawable.muxing, R.drawable.tuxing}; private static String[] nameArray = {"水星", "金星", "地球", "火星", "木星", "土星"}; private static String[] descArray = { "水星是太阳系八大行星最内侧也是最小的一颗行星,也是离太阳最近的行星", "金星是太阳系八大行星之一,排行第二,距离太阳0.725天文单位", "地球是太阳系八大行星之一,排行第三,也是太阳系中直径、质量和密度最大的类地行星,距离太阳1.5亿公里", "火星是太阳系八大行星之一,排行第四,属于类地行星,直径约为地球的53%", "木星是太阳系八大行星中体积最大、自转最快的行星,排行第五。它的质量为太阳的千分之一,但为太阳系中其它七大行星质量总和的2.5倍", "土星为太阳系八大行星之一,排行第六,体积仅次于木星" }; public static List<Planet> getDefaultList() { List<Planet> planetList = new ArrayList<Planet>(); for (int i = 0; i < iconArray.length; i++) { planetList.add(new Planet(iconArray[i], nameArray[i], descArray[i])); } return planetList; } }
PlanetGridAdapter
package com.example.myapplication; import android.annotation.SuppressLint; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import java.util.List; @SuppressLint("DefaultLocale") public class PlanetGridAdapter extends BaseAdapter implements OnItemClickListener, OnItemLongClickListener { private Context mContext; // 声明一个上下文对象 private List<Planet> mPlanetList; // 声明一个行星信息列表 // 行星适配器的构造方法,传入上下文与行星列表 public PlanetGridAdapter(Context context, List<Planet> planet_list) { mContext = context; mPlanetList = planet_list; } // 获取网格项的个数 public int getCount() { return mPlanetList.size(); } // 获取网格项的数据 public Object getItem(int arg0) { return mPlanetList.get(arg0); } // 获取网格项的编号 public long getItemId(int arg0) { return arg0; } // 获取指定位置的网格项视图 public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { // 转换视图为空 holder = new ViewHolder(); // 创建一个新的视图持有者 // 根据布局文件item_grid.xml生成转换视图对象 convertView = LayoutInflater.from(mContext).inflate(R.layout.item_grid, null); holder.iv_icon = convertView.findViewById(R.id.iv_icon); holder.tv_name = convertView.findViewById(R.id.tv_name); holder.tv_desc = convertView.findViewById(R.id.tv_desc); convertView.setTag(holder); // 将视图持有者保存到转换视图当中 } else { // 转换视图非空 // 从转换视图中获取之前保存的视图持有者 holder = (ViewHolder) convertView.getTag(); } Planet planet = mPlanetList.get(position); holder.iv_icon.setImageResource(planet.image); // 显示行星的图片 holder.tv_name.setText(planet.name); // 显示行星的名称 holder.tv_desc.setText(planet.desc); // 显示行星的描述 return convertView; } // 定义一个视图持有者,以便重用网格项的视图资源 public final class ViewHolder { public ImageView iv_icon; // 声明行星图片的图像视图对象 public TextView tv_name; // 声明行星名称的文本视图对象 public TextView tv_desc; // 声明行星描述的文本视图对象 } // 处理网格项的点击事件,由接口OnItemClickListener触发 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String desc = String.format("您点击了第%d个行星,它的名字是%s", position + 1, mPlanetList.get(position).name); Toast.makeText(mContext, desc, Toast.LENGTH_LONG).show(); } // 处理网格项的长按事件,由接口OnItemLongClickListener触发 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { String desc = String.format("您长按了第%d个行星,它的名字是%s", position + 1, mPlanetList.get(position).name); Toast.makeText(mContext, desc, Toast.LENGTH_LONG).show(); return true; } }
MainActivity
package com.example.myapplication; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.GridView; import android.widget.ListView; import android.widget.Spinner; import androidx.appcompat.app.AppCompatActivity; import java.util.List; public class MainActivity extends AppCompatActivity { private final static String TAG = "GridViewActivity"; private GridView gv_planet; // 声明一个网格视图对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); List<Planet> planetList = Planet.getDefaultList(); // 构建一个行星列表的网格适配器 PlanetGridAdapter adapter = new PlanetGridAdapter(this, planetList); // 从布局视图中获取名叫gv_planet的网格视图 gv_planet = findViewById(R.id.gv_planet); gv_planet.setAdapter(adapter); // 设置网格视图的适配器 gv_planet.setOnItemClickListener(adapter); // 设置网格视图的点击监听器 gv_planet.setOnItemLongClickListener(adapter); // 设置网格视图的长按监听器 initDividerSpinner(); // 初始化拉伸模式的下拉框 } // 初始化拉伸模式的下拉框 private void initDividerSpinner() { ArrayAdapter<String> dividerAdapter = new ArrayAdapter<String>(this, R.layout.item_select, dividerArray); Spinner sp_stretch = findViewById(R.id.sp_stretch); sp_stretch.setPrompt("请选择拉伸模式"); // 设置下拉框的标题 sp_stretch.setAdapter(dividerAdapter); // 设置下拉框的数组适配器 sp_stretch.setSelection(0); // 设置下拉框默认显示第一项 // 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法 sp_stretch.setOnItemSelectedListener(new DividerSelectedListener()); } private String[] dividerArray = { "不显示分隔线", "不拉伸(NO_STRETCH)", "拉伸列宽(COLUMN_WIDTH)", "列间空隙(STRETCH_SPACING)", "左右空隙(SPACING_UNIFORM)", "使用padding显示全部分隔线" }; class DividerSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { int dividerPad = Utils.dip2px(MainActivity.this, 2); // 定义间隔宽度为2dp gv_planet.setBackgroundColor(Color.CYAN); // 设置背景颜色 gv_planet.setHorizontalSpacing(dividerPad); // 设置列表项在水平方向的间距 gv_planet.setVerticalSpacing(dividerPad); // 设置列表项在垂直方向的间距 gv_planet.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); // 设置拉伸模式 gv_planet.setColumnWidth(Utils.dip2px(MainActivity.this, 120)); // 设置每列宽度为120dp gv_planet.setPadding(0, 0, 0, 0); // 设置网格视图的四周间距 if (arg2 == 0) { // 不显示分隔线 gv_planet.setBackgroundColor(Color.WHITE); gv_planet.setHorizontalSpacing(0); gv_planet.setVerticalSpacing(0); } else if (arg2 == 1) { // 不拉伸(NO_STRETCH) gv_planet.setStretchMode(GridView.NO_STRETCH); } else if (arg2 == 2) { // 拉伸列宽(COLUMN_WIDTH) gv_planet.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); } else if (arg2 == 3) { // 列间空隙(STRETCH_SPACING) gv_planet.setStretchMode(GridView.STRETCH_SPACING); } else if (arg2 == 4) { // 左右空隙(SPACING_UNIFORM) gv_planet.setStretchMode(GridView.STRETCH_SPACING_UNIFORM); } else if (arg2 == 5) { // 使用padding显示全部分隔线 gv_planet.setPadding(dividerPad, dividerPad, dividerPad, dividerPad); } } public void onNothingSelected(AdapterView<?> arg0) {} } }