Android笔记(七十六) 点菜DEMO
2016-01-17 04:31
549 查看
一个朋友让看一下他的代码,一个点菜的功能,他和我一样,初学者,代码比我的都混乱,也是醉了,干脆想着自己写个demo给他看,原本想着听简单,半个小时应该就可以搞定,真正写的时候,画了3h+,汗颜。。。
现在将过程捋一下,做个备忘:
原本想的时候,不就是一个ListView么,每个item除了菜品信息之外,包含两个按钮,和一个EditText,用来修改数量,于是有了第一版(请忽略界面):
MainActivity.java
activity_main.xml
Food.java
ShowFoodAdapter.java
item_show_food.xml
但是点击+-按钮却没有效果,通过log发现foodCount值是随着点击按钮变化的,只是没有更新在UI上而已,添加并执行notifyDataSetChanged()方法之后,还是出现了问题,倒是可以修改EditText控件了,但是是修改的别的Item的,也就是说点了AItem中的按钮,BItem中的EditText改变了,并且滑动屏幕的话,也会随机改变。这招行不通,找别的办法,想想在点击的时候,传入position,然后根据position来修改控件内容。那么就需要自定义点击事件了。
ShowFoodAdapter.java
然后在提交菜单的时候又遇到问题了,我是使用for循环,配合ListView的getChildCount()和getChildAt()来获取修改了数量的菜品,但是发现这个方法只能获取到屏幕中显示的Item中的数据,而没有显示的Item则获取不到,直接使用下标来获取没有显示的Item的内容,会报空指针,QQ群里求助,被告知数据和界面要分开,也就是M层和V层要剥离开来,这种情况,可以直接在数据源下手,那么问题迎刃而解,数据是在Adapter中修改的,那么在Adapter中加一个直接返回修改后的数据源的方法不就行了!
ShowFoodAdapter.java
MainActivity.java
SelectFoodActivity.java
至此,功能完成,当然还有很多需要优化的地方,譬如界面,因为仅仅是说明一下思路,这里就不展开了,回头有时间写个完整的。
现在将过程捋一下,做个备忘:
原本想的时候,不就是一个ListView么,每个item除了菜品信息之外,包含两个按钮,和一个EditText,用来修改数量,于是有了第一版(请忽略界面):
MainActivity.java
package com.example.menutest; import java.util.ArrayList; import java.util.List; import com.example.menutest.adapter.ShowFoodAdapter; import com.example.menutest.bean.Food; import android.app.Activity; import android.os.Bundle; import android.widget.Button; import android.widget.ListView; public class MainActivity extends Activity { private ListView lv_foods; private Button bt_submit; private List<Food> foodsList = new ArrayList<Food>(); private ShowFoodAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); adapter = new ShowFoodAdapter(foodsList, this); lv_foods.setAdapter(adapter); } // 初始化菜品数据 private void initData() { foodsList.add(new Food("bawangshizitou", "霸王狮子头", 23)); foodsList.add(new Food("dongbeiguobaorou", "东北锅包肉", 34)); foodsList.add(new Food("haomiganfanbazirou", "好米干饭把子肉", 45)); foodsList.add(new Food("jidanzhajiangmian", "鸡蛋炸酱面", 56)); foodsList.add(new Food("kaoquanyang", "烤全羊", 67)); foodsList.add(new Food("laobeijingchaogeda", "老北京炒疙瘩", 78)); foodsList.add(new Food("lizhirou", "荔枝肉", 89)); foodsList.add(new Food("niunaikekeqiu", "牛奶可可球", 90)); foodsList.add(new Food("peigenjinzhengu", "培根金针菇", 30)); foodsList.add(new Food("qincaixiarenshuijiao", "芹菜虾仁水饺", 37)); foodsList.add(new Food("qingmingtuanzi", "清明团子", 48)); foodsList.add(new Food("shufulei", "舒芙蕾", 39)); foodsList.add(new Food("wuxiangjianglvrou", "五香酱驴肉", 27)); foodsList.add(new Food("xianshaobai", "咸烧白", 14)); foodsList.add(new Food("xinjiangchaokaorou", "新疆炒烤肉", 28)); foodsList.add(new Food("xuedouduntihua", "雪豆炖蹄花", 10)); foodsList.add(new Food("yangzasui", "羊杂碎", 27)); foodsList.add(new Food("yerongtianjiangmaifen", "椰蓉甜姜麦芬", 16)); foodsList.add(new Food("zhenfengji", "蒸风鸡", 53)); } // 查找组件 private void initView() { lv_foods = (ListView) findViewById(R.id.lv_foods); bt_submit = (Button) findViewById(R.id.bt_submit); } }
activity_main.xml
<LinearLayout 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:orientation="vertical" tools:context="com.example.menutest.MainActivity" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="选择菜品" /> <ListView android:id="@+id/lv_foods" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" > </ListView> <Button android:id="@+id/bt_submit" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="OK" /> </LinearLayout>
Food.java
package com.example.menutest.bean; public class Food { private String foodImageName; private String foodName; private int foodPrice; private int foodCount; public Food(String foodImageName, String foodName, int foodPrice, int foodCount) { super(); this.foodImageName = foodImageName; this.foodName = foodName; this.foodPrice = foodPrice; this.foodCount = foodCount; } public Food(String foodName, int foodPrice, int foodCount) { super(); this.foodName = foodName; this.foodPrice = foodPrice; this.foodCount = foodCount; } public Food(String foodImageName, String foodName, int foodPrice) { super(); this.foodImageName = foodImageName; this.foodName = foodName; this.foodPrice = foodPrice; } public Food() { super(); } public String getFoodImageName() { return foodImageName; } public void setFoodImageName(String foodImageName) { this.foodImageName = foodImageName; } public String getFoodName() { return foodName; } public void setFoodName(String foodName) { this.foodName = foodName; } public int getFoodPrice() { return foodPrice; } public void setFoodPrice(int foodPrice) { this.foodPrice = foodPrice; } public int getFoodCount() { return foodCount; } public void setFoodCount(int foodCount) { this.foodCount = foodCount; } }
ShowFoodAdapter.java
package com.example.menutest.adapter; import java.io.IOException; import java.util.List; import com.example.menutest.R; import com.example.menutest.bean.Food; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; public class ShowFoodAdapter extends BaseAdapter { private List<Food> mList; private Context mContext; private int foodCount; private ViewHolder viewHolder; public ShowFoodAdapter(List<Food> list, Context context) { this.mContext = context; this.mList = list; } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { viewHolder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.item_show_foods, null); viewHolder.iv_food_image = (ImageView) convertView.findViewById(R.id.iv_food_image); viewHolder.tv_food_name = (TextView) convertView.findViewById(R.id.tv_food_name); viewHolder.tv_food_price = (TextView) convertView.findViewById(R.id.tv_food_price); viewHolder.et_food_count = (EditText) convertView.findViewById(R.id.et_food_count); viewHolder.bt_minus = (Button) convertView.findViewById(R.id.bt_minus); viewHolder.bt_plus = (Button) convertView.findViewById(R.id.bt_plus); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } try { Bitmap bitmap = BitmapFactory .decodeStream(mContext.getAssets().open(mList.get(position).getFoodImageName() + ".jpg")); viewHolder.iv_food_image.setImageBitmap(bitmap); } catch (IOException e) { Log.d("TTTT", "图片设置失败,位置:" + position); e.printStackTrace(); } viewHolder.tv_food_name.setText(mList.get(position).getFoodName()); viewHolder.tv_food_price.setText(mList.get(position).getFoodPrice() + "元/份"); viewHolder.bt_minus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewHolder.et_food_count.setText(--foodCount + ""); } }); viewHolder.bt_plus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewHolder.et_food_count.setText(++foodCount + ""); } }); return convertView; } // ViewHolder class ViewHolder { ImageView iv_food_image; TextView tv_food_name, tv_food_price; EditText et_food_count; Button bt_minus, bt_plus; } }
item_show_food.xml
<?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="wrap_content" android:gravity="center" android:orientation="horizontal" > <ImageView android:id="@+id/iv_food_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/bawangshizitou" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/tv_food_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="红烧肉" /> <TextView android:id="@+id/tv_food_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="10" /> </LinearLayout> <Button android:id="@+id/bt_minus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="-" /> <EditText android:id="@+id/et_food_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0" /> <Button android:id="@+id/bt_plus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+" /> </LinearLayout>
但是点击+-按钮却没有效果,通过log发现foodCount值是随着点击按钮变化的,只是没有更新在UI上而已,添加并执行notifyDataSetChanged()方法之后,还是出现了问题,倒是可以修改EditText控件了,但是是修改的别的Item的,也就是说点了AItem中的按钮,BItem中的EditText改变了,并且滑动屏幕的话,也会随机改变。这招行不通,找别的办法,想想在点击的时候,传入position,然后根据position来修改控件内容。那么就需要自定义点击事件了。
ShowFoodAdapter.java
package com.example.menutest.adapter; import java.io.IOException; import java.util.List; import com.example.menutest.R; import com.example.menutest.bean.Food; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; public class ShowFoodAdapter extends BaseAdapter { private List<Food> mList; private Context mContext; // private int foodCount; private ViewHolder viewHolder; public ShowFoodAdapter(List<Food> list, Context context) { this.mContext = context; this.mList = list; } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { viewHolder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.item_show_foods, null); viewHolder.iv_food_image = (ImageView) convertView.findViewById(R.id.iv_food_image); viewHolder.tv_food_name = (TextView) convertView.findViewById(R.id.tv_food_name); viewHolder.tv_food_price = (TextView) convertView.findViewById(R.id.tv_food_price); viewHolder.et_food_count = (EditText) convertView.findViewById(R.id.et_food_count); viewHolder.bt_minus = (Button) convertView.findViewById(R.id.bt_minus); viewHolder.bt_plus = (Button) convertView.findViewById(R.id.bt_plus); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } try { Bitmap bitmap = BitmapFactory .decodeStream(mContext.getAssets().open(mList.get(position).getFoodImageName() + ".jpg")); viewHolder.iv_food_image.setImageBitmap(bitmap); } catch (IOException e) { Log.d("TTTT", "图片设置失败,位置:" + position); e.printStackTrace(); } viewHolder.tv_food_name.setText(mList.get(position).getFoodName()); viewHolder.tv_food_price.setText(mList.get(position).getFoodPrice() + "元/份"); // 直接从数据源中拿取数量,下面的按钮点击,直接修改数据源中的数据 viewHolder.et_food_count.setText(mList.get(position).getFoodCount() + ""); viewHolder.bt_minus.setOnClickListener(new ItemButtonOnClickListener(position)); viewHolder.bt_plus.setOnClickListener(new ItemButtonOnClickListener(position)); return convertView; } // ViewHolder class ViewHolder { ImageView iv_food_image; TextView tv_food_name, tv_food_price; EditText et_food_count; Button bt_minus, bt_plus; @Override public String toString() { return tv_food_name.getText().toString(); } } class ItemButtonOnClickListener implements View.OnClickListener { private int position; // 获取EditeText此时正显示的数量 private int foodCount = Integer.parseInt(viewHolder.et_food_count.getText().toString()); public ItemButtonOnClickListener(int position) { this.position = position; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt_plus: // 数量+1 foodCount++; // 将数据源中的数量修改 mList.get(position).setFoodCount(foodCount); // 刷新显示 notifyDataSetChanged(); break; case R.id.bt_minus: foodCount--; if (foodCount <= 0) { mList.get(position).setFoodCount(0); } else { mList.get(position).setFoodCount(foodCount); } notifyDataSetChanged(); break; } } } }
然后在提交菜单的时候又遇到问题了,我是使用for循环,配合ListView的getChildCount()和getChildAt()来获取修改了数量的菜品,但是发现这个方法只能获取到屏幕中显示的Item中的数据,而没有显示的Item则获取不到,直接使用下标来获取没有显示的Item的内容,会报空指针,QQ群里求助,被告知数据和界面要分开,也就是M层和V层要剥离开来,这种情况,可以直接在数据源下手,那么问题迎刃而解,数据是在Adapter中修改的,那么在Adapter中加一个直接返回修改后的数据源的方法不就行了!
ShowFoodAdapter.java
package com.example.menutest.adapter; import java.io.IOException; import java.util.List; import com.example.menutest.R; import com.example.menutest.bean.Food; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; public class ShowFoodAdapter extends BaseAdapter { private List<Food> mList; private Context mContext; // private int foodCount; private ViewHolder viewHolder; public ShowFoodAdapter(List<Food> list, Context context) { this.mContext = context; this.mList = list; } // 返回修改过数量之后的List public List getSelectedFoodList() { return mList; } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { viewHolder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.item_show_foods, null); viewHolder.iv_food_image = (ImageView) convertView.findViewById(R.id.iv_food_image); viewHolder.tv_food_name = (TextView) convertView.findViewById(R.id.tv_food_name); viewHolder.tv_food_price = (TextView) convertView.findViewById(R.id.tv_food_price); viewHolder.et_food_count = (EditText) convertView.findViewById(R.id.et_food_count); viewHolder.bt_minus = (Button) convertView.findViewById(R.id.bt_minus); viewHolder.bt_plus = (Button) convertView.findViewById(R.id.bt_plus); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } try { Bitmap bitmap = BitmapFactory .decodeStream(mContext.getAssets().open(mList.get(position).getFoodImageName() + ".jpg")); viewHolder.iv_food_image.setImageBitmap(bitmap); } catch (IOException e) { Log.d("TTTT", "图片设置失败,位置:" + position); e.printStackTrace(); } viewHolder.tv_food_name.setText(mList.get(position).getFoodName()); viewHolder.tv_food_price.setText(mList.get(position).getFoodPrice() + "元/份"); // 直接从数据源中拿取数量,下面的按钮点击,直接修改数据源中的数据 viewHolder.et_food_count.setText(mList.get(position).getFoodCount() + ""); viewHolder.bt_minus.setOnClickListener(new ItemButtonOnClickListener(position)); viewHolder.bt_plus.setOnClickListener(new ItemButtonOnClickListener(position)); return convertView; } // ViewHolder class ViewHolder { ImageView iv_food_image; TextView tv_food_name, tv_food_price; EditText et_food_count; Button bt_minus, bt_plus; @Override public String toString() { return tv_food_name.getText().toString(); } } class ItemButtonOnClickListener implements View.OnClickListener { private int position; // 获取EditeText此时正显示的数量 private int foodCount = Integer.parseInt(viewHolder.et_food_count.getText().toString()); public ItemButtonOnClickListener(int position) { this.position = position; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt_plus: // 数量+1 foodCount++; // 将数据源中的数量修改 mList.get(position).setFoodCount(foodCount); // 刷新显示 notifyDataSetChanged(); break; case R.id.bt_minus: foodCount--; if (foodCount <= 0) { mList.get(position).setFoodCount(0); } else { mList.get(position).setFoodCount(foodCount); } notifyDataSetChanged(); break; } } } }
MainActivity.java
package com.example.menutest; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import com.example.menutest.adapter.ShowFoodAdapter; import com.example.menutest.bean.Food; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ListView; public class MainActivity extends Activity { private ListView lv_foods; private Button bt_submit; private List<Food> foodsList = new ArrayList<Food>(); private ShowFoodAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); adapter = new ShowFoodAdapter(foodsList, this); lv_foods.setAdapter(adapter); bt_submit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { List<Food> selectedFoodList = adapter.getSelectedFoodList(); Intent intent = new Intent(MainActivity.this, SelectFoodActivity.class); intent.putExtra("selectFood", (Serializable) selectedFoodList); startActivity(intent); } }); } // 初始化菜品数据 private void initData() { foodsList.add(new Food("bawangshizitou", "霸王狮子头", 23)); foodsList.add(new Food("dongbeiguobaorou", "东北锅包肉", 34)); foodsList.add(new Food("haomiganfanbazirou", "好米干饭把子肉", 45)); foodsList.add(new Food("jidanzhajiangmian", "鸡蛋炸酱面", 56)); foodsList.add(new Food("kaoquanyang", "烤全羊", 67)); foodsList.add(new Food("laobeijingchaogeda", "老北京炒疙瘩", 78)); foodsList.add(new Food("lizhirou", "荔枝肉", 89)); foodsList.add(new Food("niunaikekeqiu", "牛奶可可球", 90)); foodsList.add(new Food("peigenjinzhengu", "培根金针菇", 30)); foodsList.add(new Food("qincaixiarenshuijiao", "芹菜虾仁水饺", 37)); foodsList.add(new Food("qingmingtuanzi", "清明团子", 48)); foodsList.add(new Food("shufulei", "舒芙蕾", 39)); foodsList.add(new Food("wuxiangjianglvrou", "五香酱驴肉", 27)); foodsList.add(new Food("xianshaobai", "咸烧白", 14)); foodsList.add(new Food("xinjiangchaokaorou", "新疆炒烤肉", 28)); foodsList.add(new Food("xuedouduntihua", "雪豆炖蹄花", 10)); foodsList.add(new Food("yangzasui", "羊杂碎", 27)); foodsList.add(new Food("yerongtianjiangmaifen", "椰蓉甜姜麦芬", 16)); foodsList.add(new Food("zhenfengji", "蒸风鸡", 53)); } // 查找组件 private void initView() { lv_foods = (ListView) findViewById(R.id.lv_foods); bt_submit = (Button) findViewById(R.id.bt_submit); } }
SelectFoodActivity.java
package com.example.menutest; import java.util.ArrayList; import java.util.List; import com.example.menutest.bean.Food; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; public class SelectFoodActivity extends Activity { private ListView lv_select_food; private TextView tv_money_count; private ArrayAdapter<String> adapter; private int moneyCount; private List<String> list = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_food); initView(); Intent intent = getIntent(); List<Food> selectFood = (List<Food>) intent.getSerializableExtra("selectFood"); for (int i = 0; i < selectFood.size(); i++) { if (selectFood.get(i).getFoodCount() == 0) { continue; } else { list.add(selectFood.get(i).getFoodName() + ",共 " + selectFood.get(i).getFoodCount() + " 份,每份 " + selectFood.get(i).getFoodPrice() + " 元"); moneyCount += selectFood.get(i).getFoodPrice() * selectFood.get(i).getFoodCount(); } } adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); lv_select_food.setAdapter(adapter); tv_money_count.setText("共计: " + moneyCount + " 元"); } private void initView() { lv_select_food = (ListView) findViewById(R.id.lv_select_food); tv_money_count = (TextView) findViewById(R.id.tv_money_count); } }
至此,功能完成,当然还有很多需要优化的地方,譬如界面,因为仅仅是说明一下思路,这里就不展开了,回头有时间写个完整的。
相关文章推荐
- Android 数据存储之 SQLite数据库存储
- Android 值动画 动画要达到的效果 跟动画的执行过程绑定
- android扫描二维码:已经封装为jar包,实现扫描只需一步
- <Android>关于 Android 中的OnScrollListener监听接口
- Android 数据存储之 SharedPreferences储存
- Android 使用Android Studio + Gradle 或 命令行 进行apk签名打包
- the latest ButterKnife and Android-Butterknife-Zelezny
- Android \uFEFF问题
- 功能分解——Android下画分时图与k线图有感
- Android自定义ToolBar布局
- 【Android】jar包Proguard混淆方法
- Android笔记——Android中数据的存储方式(三)
- Android性能优化之Splash页应该这样设计
- 通过Baseadpter自定义Adapter适配器的学习笔记
- 解决Android Studio中文乱码问题
- Android动画教程
- Android图片操作-保存图片到SD卡
- Android:对象序列化(05)
- Android基本控件示例GridView(05)
- Android怎么打开和调用系统自带的程序示例(06)