一、实现的效果
说明:内容会随着手指的滑动而上下滚动,点击加号,数字会相应的增加,点击减号,数字会相应的减少
二、实现原理
通俗的讲,Data source通过Adapter被投射到ListView展现到屏幕上
三、实现过程
1. 规定好这个Activity的布局文件Activity_main.xml,里是一个LinearLayout嵌套一个GridLayout,特别注意GridLayot的列设置为2;
2. 规定好每一个item的布局文件item_layout.xml,里面规定好每一个item的元素,ImageView,TextView的位置、大小等。
3. 编写商品类,包括一个商品应该有的所有属性,并添加get、set方法
4. 编写MainActivity,主要是绑定布局文件,添加事件源,在这个例子中我是手动添加一个商品队列list,在实际开发过程中,多半是从数据库发过来数据,操作方式类似
5. 编写MyAdapter,继承BaseAdapter,重写里面的方法
四、代码实现
1.Activity的布局文件Activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:backgroundTint="#E5E4E4" android:background="#E5E4E4"> <GridView android:id="@+id/parent_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:horizontalSpacing="15dp" android:numColumns="2" android:verticalSpacing="15dp"> </GridView> </LinearLayout>
2.item的布局文件item_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="#FFFFFF" android:orientation="vertical" > <!--商品图片展示 --> <ImageView android:id="@+id/logo" android:layout_width="wrap_content" android:layout_height="200dp"/> <!-- 商品介绍 --> <TextView android:id="@+id/introduce" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:textSize="20sp"/> <!-- 价格和数量 --> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <!-- 价格 --> <TextView android:id="@+id/price" android:layout_width="70dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="15dp" android:textColor="#ED2342" android:textSize="20sp" /> <!--减号--> <ImageView android:id="@+id/decrease" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginTop="10dp" /> <!--数量--> <TextView android:id="@+id/mount" android:layout_marginTop="10dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_width="wrap_content" android:layout_height="30dp" android:background="#FFFFFF" android:textSize="20sp"/> <!-- 加号 --> <ImageView android:id="@+id/add" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginRight="5dp" android:layout_marginTop="10dp"/> </LinearLayout> </LinearLayout>
3.商品类
package com.example.crzayzhang.testgridlayout; /** * Created by CrzayZhang on 2015/10/27. */ /**ogo,商品介绍introduce,价格price,减少按钮decrease,数量mount,添加按钮add * 由于logo,decrease,add是由有图片构造,所以定义成一个Drawable的id,int型 * 还有各种参数的get,set方法 */ public class Goods { public int logo; public String introduce; public String price; public int decrease; public int mount; public int add; public Goods(int logo, String introduce, String price, int decrease, int mount, int add) { this.logo = logo; this.introduce = introduce; this.price = price; this.decrease = decrease; this.mount = mount; this.add = add; } public int getLogo() { return logo; } public void setLogo(int logo) { this.logo = logo; } public String getIntroduce() { return introduce; } public void setIntroduce(String introduce) { this.introduce = introduce; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public int getDecrease() { return decrease; } public void setDecrease(int decrease) { this.decrease = decrease; } public int getMount() { return mount; } public void setMount(int mount) { this.mount = mount; } public int getAdd() { return add; } public void setAdd(int add) { this.add = add; } }
4.MainActivity
package com.example.crzayzhang.testgridlayout; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import java.util.ArrayList; import android.widget.GridView; public class MainActivity extends ActionBarActivity { public ArrayList<Goods> list= new ArrayList<Goods>(); //存储商品的队列,在这里要特别注意只能new一次,因为这涉及到后面的刷新问题 //只能对所有的数据在同一个队列里进行操作,也就是说地址只能有一个 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);//将这个主Activity绑定相应的布局文件 GridView gv=(GridView)findViewById(R.id.parent_layout);//通过id找到最外面的GridView MyAdapter adapter= new MyAdapter(this, getData());//构造新的适配器 gv.setAdapter(adapter);//把适配器应用到gv上 adapter.notifyDataSetChanged();//实时刷新 } /** * 这是返回队列的方法。如果是连接数据库的话,可以另外写一个方法,返回相应的内容 * * @return */ private ArrayList<Goods> getData() { Goods goods=null; //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_1,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_2,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_3,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_4,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_5,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_6,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_7,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_8,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_9,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); goods=new Goods(R.drawable.food_10,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); goods=new Goods(R.drawable.food_1,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_2,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_3,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_4,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_5,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_6,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); //------------------------------------------------------------------------- goods=new Goods(R.drawable.food_7,"义莉糖醇莫子酥约25*6g/份","¥7.20",R.drawable.button_decrease,0,R.drawable.button_add); list.add(goods); return list; } /** * 这个方法暂时可以不用管,这是新版SDK添加的内容 * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } /** * 这个函数也不用管,本idom中也没有用到相应的内容 * @param item * @return */ @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
5.MyAdapter
package com.example.crzayzhang.testgridlayout; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.List; /** * Created by CrzayZhang on 2015/10/27. */ /** * 适配器类 */ public class MyAdapter extends BaseAdapter{ private List<Goods> list;//存储商品的队列,也就是数据源 private Context context;//传过来的MainActivity private LayoutInflater layoutinflater;// /** * 构造方法。将MainActivity,存储Goods对象的list队列传过来,另外 * @param context * @param list */ public MyAdapter(Context context, List<Goods> list) { this.context = context; this.list = list; //从MainActivity获取LayoutInflater对象,它的作用是将xml布局文件实例化为View对象类对象 this.layoutinflater = layoutinflater.from(context); } /** * 重写抽象方法,返回队列的长度 * @return */ @Override public int getCount() { return list.size(); } /** * 可以暂时不用管,主要重写的是getView方法 * @param position * @return */ @Override public Object getItem(int position) { return null; } /** * 可以暂时不用管,主要重写的是getView方法 * @param position * @return */ @Override public long getItemId(int position) { return 0; } /** * * @param position 队列中的位置 * @param convertView * @param parent * @return */ @Override public View getView(final int position, View convertView,final ViewGroup parent) { final ViewHolder vh = new ViewHolder();//创建一个ViewHolder对象,相当于一个空的View,还没有任何数据在里面 convertView = layoutinflater.inflate(R.layout.item_layout, null);//设置convertView的布局是item_layout //将vh的各个元素与convertView进行绑定 vh.logo = (ImageView) convertView.findViewById(R.id.logo); vh.introduce = (TextView) convertView.findViewById(R.id.introduce); vh.price = (TextView) convertView.findViewById(R.id.price); vh.decrease = (ImageView) convertView.findViewById(R.id.decrease); vh.mount = (TextView) convertView.findViewById(R.id.mount); vh.add = (ImageView) convertView.findViewById(R.id.add); final Goods item=list.get(position); //实例化vh的各个元素 vh.logo.setBackgroundResource(item.getLogo()); vh.introduce.setText(item.getIntroduce()); vh.price.setText(item.getPrice()); vh.decrease.setBackgroundResource(item.getDecrease()); vh.mount.setText(item.getMount() + ""); vh.add.setBackgroundResource(item.getAdd()); //给减少按钮按钮添加监听器,执行点击事件时候,减少list相应位置上元素的mount,这就从数据源上执行了操作 vh.decrease.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(list.get(position).getMount()>0){ int t = list.get(position).getMount() - 1; list.get(position).setMount(t); updata(); } } }); //给添加按钮按钮添加监听器,执行点击事件时候,增加list相应位置上元素的mount vh.add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int t=list.get(position).getMount()+1; list.get(position).setMount(t); updata(); } }); return convertView; } /** * 刷新数据源,重新执行一遍映射的=操作 * 窗体上的数据呈现就会立刻改变 */ public void updata(){ this.notifyDataSetChanged(); } /** * 这个类只有成员变量,这个就是你在每一个item里想呈现的内容 */ public class ViewHolder { public ImageView logo;//商品图片 public TextView introduce;//商品描述 public TextView price;//商品价格 public ImageView decrease;//减少按钮 public TextView mount;//数量 public ImageView add;//添加按钮 } }
五、感受
学习技术,只有通过自己动手完全实现一遍才能真正理解其实现过程和原理,多动手才是学好技术的关键