Android Studio 安卓开发学习---双ListView布局、ListView适配器、ListView分类实现
前言学校要求做安卓项目,想实现一个食堂点餐的app,初学Java,有很多不足,下面仅作为个人经验的分享。欢迎大佬的指点,也希望对后来的同学有用。1. 双 ListView 布局我碰到的第一个难题是双ListView如何实现,其实很简单,只需要在一个xml中,使用一个线性布局即可。为了实现日后的双ListView联动这是必不可少的第一步,关于ListView联动我日后在写。<?xm...
前言
学校要求做安卓项目,想实现一个食堂点餐的app,初学Java,有很多不足,下面仅作为个人经验的分享。欢迎大佬的指点,也希望对后来的同学有用。
1. 双 ListView 布局
我碰到的第一个难题是双ListView如何实现,其实很简单,只需要在一个xml中,使用一个线性布局即可。
为了实现日后的双ListView联动这是必不可少的第一步,关于ListView联动我日后在写。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Shop_list.BuyingFoodInShuiYunActivity"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:padding="10dp"
android:background="@mipmap/canteenshuiyun">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:layout_marginLeft="120dp"
android:text="当前等待人数:36" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ListView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scrollbars="none" >
</ListView>
<View android:layout_width="1dp"
android:background="@android:color/black"
android:layout_height="match_parent"/>
<ListView
android:id="@+id/content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:scrollbars="none" >
</ListView>
</LinearLayout>
</LinearLayout>
首先用相对布局在上方放置一个Title,再用线性布局实现下方的两个ListView.
2. ListView适配器
适配器的写法比较固定。不同的ListView可以用不同的Adapter来填充内容。
(1).item的封装
对于这方面我是用“封装”的概念理解的。比如以上述布局中的id为content的ListView为例子,首先我们需要明白其需要用什么样的XML布局去渲染每一个item.
就是这样啦。下附代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:padding="10dp"
>
<ImageView
android:id="@+id/item_foodcontent_iv"
android:layout_width="120dp"
android:layout_height="80dp"
android:src="@mipmap/ic_launcher"
android:scaleType="fitXY"/>
<TextView
android:id="@+id/item_foodcontent_tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/item_foodcontent_iv"
android:layout_marginTop="10dp"
android:text="food"
android:layout_marginLeft="10dp"
android:textStyle="bold"
android:textSize="20sp"/>
<TextView
android:id="@+id/item_foodcontent_tv_titlenumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/item_foodcontent_tv_title"
android:text="x"
android:layout_marginTop="10dp"
android:textStyle="bold"
android:textSize="20sp"
android:layout_marginLeft="10dp"/>
<TextView
android:id="@+id/item_foodcontent_tv_simple_introduction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/item_foodcontent_tv_title"
android:layout_alignBottom="@id/item_foodcontent_iv"
android:text="A simple introduction of the food"/>
<ImageView
android:id="@+id/item_foodcontent_iv_next"
android:layout_width="28dp"
android:layout_height="46dp"
android:layout_marginTop="0dp"
android:layout_alignParentRight="true"
android:src="@mipmap/expend" />
<ImageView
android:id="@+id/item_foodcontent_iv_addbutton"
android:layout_width="28dp"
android:layout_height="46dp"
android:src="@mipmap/addbutton"
android:layout_alignParentRight="true"
android:layout_marginTop="45dp"/>
</RelativeLayout>
给每一个部分,取上规定好的id,方便我们日后查找。
弄明白我们的布局后,下面封装的内容就非常清楚了。
我们将XML封装的Java类命名为:FoodContentBean
package com.example.buyfood.Bean;
public class FoodContentBean {
private String foodName;
private String foodIntroduce;
private String foodNumber;
private int picID;
//下面是类别
private String type;
private String typenumber;
public FoodContentBean(String foodName, String foodIntroduce, String foodNumber, int picID) {
this.foodName = foodName;
this.foodIntroduce = foodIntroduce;
this.foodNumber = foodNumber;
this.picID = picID;
}
public FoodContentBean(String type, String typenumber) {
this.type = type;
this.typenumber = typenumber;
}
public FoodContentBean() {
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public String getFoodIntroduce() {
return foodIntroduce;
}
public void setFoodIntroduce(String foodIntroduce) {
this.foodIntroduce = foodIntroduce;
}
public String getFoodNumber() {
return foodNumber;
}
public void setFoodNumber(String foodNumber) {
this.foodNumber = foodNumber;
}
public int getPicID() {
return picID;
}
public void setPicID(int picID) {
this.picID = picID;
}
//下面是类别的getset方法
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTypenumber() {
return typenumber;
}
public void setTypenumber(String typenumber) {
this.typenumber = typenumber;
}
}
其中的变量就是我们布局中的图片、文字、按钮(其实也是图片)。
设置好构造方法,设置好get、set方法即可。
(2).资源的获取
我们初学,项目一般处于本地获取资源的状态,我们直接把资源写到代码当中!命名为:FoodContentUtils
package com.example.buyfood.Bean;
import com.example.buyfood.R;
import java.util.ArrayList;
import java.util.List;
public class FoodContentUtils {
private static final int[] FoodpicID = {R.mipmap.ic_launcher_round};
public static List<FoodContentBean> getAllFoodList(){
List<FoodContentBean> list = new ArrayList<>();
//食物
String foodname = "食物";
String foodnumber;
int Foodnumber = 1;
String foodintroduce = "该处是食物简介";
int picID = FoodpicID[0];
//---------------------------------------
//类别
String type = "店铺";
String typenumber;
int Typenumber=1;
//---------------------------------------
for(int i=0;i<45;i++)
{
if(i%5==0)
{
typenumber = String.valueOf(Typenumber);
Typenumber++;
FoodContentBean bean = new FoodContentBean(type,typenumber);
list.add(bean);
}
else
{
foodnumber = String.valueOf(Foodnumber);
Foodnumber++;
FoodContentBean bean = new FoodContentBean(foodname,foodintroduce,foodnumber,picID);
list.add(bean);
}
}
return list;
}
}
注意了,我在这里运用了一些比较简单的方法去规定资源List的内容,即重写FoodContentBean的构造方法,因为我们要分层实现该ListView.下面将说明这一点。
(3). Adapter写法
FoodListAdapter是BaseAdapter的子类,所以我们首先要继承它。再去实现重要的方法。
package com.example.buyfood.Shop_list;
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 com.example.buyfood.Bean.FoodContentBean;
import com.example.buyfood.R;
import java.util.List;
public class FoodListAdapter extends BaseAdapter {
Context context;
List<FoodContentBean> mDatas;
private static final int type_foodheader = 0;
private static final int type_fooditem = 1;
public FoodListAdapter(Context context, List<FoodContentBean> mDatas) {
this.context = context;
this.mDatas = mDatas;
}
@Override
// getCount决定了ListView展示的行数
public int getCount() {
return mDatas.size();
}
@Override
//返回指定位置所对应的的数据
public Object getItem(int position) {
return mDatas.get(position);
}
@Override
//返回指定位置所对应的ID
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
if(position%5==0)
{
return type_foodheader;
}else{
return type_fooditem;
}
}
@Override
public int getViewTypeCount() {
return 2;
}
//返回指定位置所对应的View
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int item_type = getItemViewType(position);
ViewHolder holder = null;
ViewHolder_foodheader holder_foodheader = null;
if(convertView==null)//将布局转化为view对象的方法
{
switch (item_type)
{
case type_foodheader:
convertView = LayoutInflater.from(context).inflate(R.layout.item_foodheader,null);
holder_foodheader = new ViewHolder_foodheader(convertView);
convertView.setTag(holder_foodheader);
break;
case type_fooditem:
convertView = LayoutInflater.from(context).inflate(R.layout.item_foodcontent_list,null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
break;
}
} else{
switch (item_type)
{
case type_foodheader:
holder_foodheader = (ViewHolder_foodheader)convertView.getTag();
break;
case type_fooditem:
holder = (ViewHolder)convertView.getTag();
break;
}
}
//加载控件中的显示
//获取集合指定位置的数据
switch (item_type)
{
case type_foodheader:
FoodContentBean foodContentBean = mDatas.get(position);
holder_foodheader.typename.setText(foodContentBean.getType());
holder_foodheader.typenumber.setText(foodContentBean.getTypenumber());
break;
case type_fooditem:
FoodContentBean foodcontentBean = mDatas.get(position);
holder.foodname.setText(foodcontentBean.getFoodName());
holder.foodpic.setImageResource(foodcontentBean.getPicID());
holder.foodintroduce.setText(foodcontentBean.getFoodIntroduce());
holder.foodnumber.setText(foodcontentBean.getFoodNumber());
break;
}
return convertView;
}
class ViewHolder{
TextView foodname,foodnumber,foodintroduce;
ImageView foodpic;
public ViewHolder(View view){
foodname = view.findViewById(R.id.item_foodcontent_tv_title);
foodnumber = view.findViewById(R.id.item_foodcontent_tv_titlenumber);
foodintroduce = view.findViewById(R.id.item_foodcontent_tv_simple_introduction);
foodpic = view.findViewById(R.id.item_foodcontent_iv);
}
}
class ViewHolder_foodheader{
TextView typename,typenumber;
public ViewHolder_foodheader(View view){
typename = view.findViewById(R.id.item_foodheader_tv_fh);
typenumber = view.findViewById(R.id.item_foodheader_tv_fhn);
}
}
}
还记得我们资源添加为什么要用奇怪的判断语句吗?
if(i%5==0)
{
typenumber = String.valueOf(Typenumber);
Typenumber++;
FoodContentBean bean = new FoodContentBean(type,typenumber);
list.add(bean);
}
else
{
foodnumber = String.valueOf(Foodnumber);
Foodnumber++;
FoodContentBean bean = new FoodContentBean(foodname,foodintroduce,foodnumber,picID);
list.add(bean);
}
这是因为我们后来的adapter中,position会随着我们的适配次数不断递增,如果我们没有提前规定好分类标题的位置,会出现位置被占用的情况,当然这是一个笨办法。
(4). 最后创建适配器
package com.example.buyfood.Shop_list;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import com.example.buyfood.Bean.FoodContentBean;
import com.example.buyfood.Bean.FoodContentUtils;
import com.example.buyfood.Bean.ShopBean;
import com.example.buyfood.Bean.ShopUntils;
import com.example.buyfood.R;
import java.util.ArrayList;
import java.util.List;
public class BuyingFoodInShuiYunActivity extends AppCompatActivity {
ListView show_Lv_title,show_Lv_foodcontent;//展示第一、第二个ListView
//ListView-shoptitle的数据源
List<ShopBean> mDatas;
List<ShopBean> allShopList;
private ShopListAdapter adapter;
//ListView-foodcontent的数据源
List<FoodContentBean> mDatas_food;
List<FoodContentBean> allFoodList;
private FoodListAdapter adapter_food;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buying_food_in_shui_yun);
//1.查找控件findviewbyid---下面的方法
initView();
//2.找到ListView-Shop的数据源------ShopUntils
mDatas = new ArrayList<>();
allShopList = ShopUntils.getAllShopList();
mDatas.addAll(allShopList);
//--------------------------------------------
//2.1 找到ListView-Food的数据源------FoodcontentUntils
mDatas_food = new ArrayList<>();
allFoodList = FoodContentUtils.getAllFoodList();
mDatas_food.addAll(allFoodList);
//3.创建适配器 BaseAdapter的子类
adapter = new ShopListAdapter(this, mDatas);
//---------------------------------------------------------
//另一个适配器
adapter_food = new FoodListAdapter(this,mDatas_food);
//4.设置适配器
show_Lv_title.setAdapter(adapter);
show_Lv_foodcontent.setAdapter(adapter_food);
}
private void initView() {
show_Lv_title = findViewById(R.id.title);
show_Lv_foodcontent = findViewById(R.id.content);
}
}
备注:initview()方法是我用来找控件的一个集成方法
最终效果:
欢迎批评指正!
更多推荐
所有评论(0)