ListActivity ListView的id为什么要用@android:id/list

本文详细探讨了在使用ListActivity时遇到的问题,包括如何正确引用ListView控件的ID,以及@id/android:list与@+id/android:list的区别。通过分析ListActivity的源码,解释了设置适配器的方法,并提供了自定义布局时ID引用的最佳实践。

今天用到ListActivity这个Activity的子类,发现了一个问题,就是以前我们在学ListActivity的时候,如果用到了ListActivity,我们用自己定义的布局的时候,ListView控件的id必须要写成@id/android:list或者@android:id/list(区别下面说),还有我用了@+id/android:list竟然也是可以的。

<ListView 
        android:id="@+id/android:list"
        android:layout_height="wrap_content"
        android:layout_width="match_parent" />

好吧,那我们开始看看ListActivity的源码吧。
用listview,必须要setAdapter()是吧,ListAcitivty中是用setListAdapter()设置适配器的。那先从ListActivity的setListAdapter()这个方法进去看看,发现会调用ensureList()这个方法

private void ensureList() {
        if (mList != null) {
            return;
        }
        setContentView(com.android.internal.R.layout.list_content_simple);

    }

mList!=null 说的就是如果你在代码中setContentView() 那么就直接返回,如果没有就设置成com.android.internal.R.layout.list_content_simple 那么我们看看这个资源文件在哪。
在我的电脑路径是在F:\sdk\platforms\android-19\data\res\layout 这下面。

<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    android:drawSelectorOnTop="false"
    />

我们看到 他的id是引用了@android:id/list,那自然我们自己写的资源文件中也要引用这个。

那我们看看@+id/android:list 和@id/android:list 有什么区别???
当你引用了Android API中定义的东西,应该适当的用 @id/android:list,另外+表示你定义了一个新的ID,意味着为R文件添加了一些东西,为什么这里@+id/android:list,R资源没有添加上这个十六进制的变量呢?我个人认为是如果添加的是android api中定义的id,那么就会去android定义的包,然后告诉它我要加这个这个资源的ID,那么就直接覆盖了android定义的包里面的R文件的ID。

再看看@id/android:list 和 @android:id/list 有什么区别???
@android:id/list 和@id/android:list其实是一样的。
第一个例子:@ id/android:list将去寻找android包内的list这个id。
第二个例子:@android:id/list,首先定义了android的包,然后告诉它查找该包内的id/list。
只是写法不同,反正最终都是会去找android.R.id.list(就像你被人打,和别人打你,都是挨打),看官方的是用@android:id/list,所以我们还是用官方说的这个吧,谁让我们是开发者。

至于id上随便定义,比如:

<ListView 
        android:id="@+id/balabala"
        android:layout_height="wrap_content"
        android:layout_width="match_parent" />

这里写图片描述
爽了吧,报错了,让你别这么干。

总结:1.用ListActivity的时候,如果你要自定义layout,那id的属性就用@android:id/list。
2.其实@android:id/list,用代码来写也是和自己+id的时候一样findViewById(android.R.id.list)

activity_main.xml <?xml version="1.0" encoding="utf-8"?> <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:background="@android:color/white" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginBottom="4dp" android:background="@color/gray" android:gravity="center_vertical"> <TextView android:id="@+id/tv_order" style="@style/tvNavigationBarStyle" android:text="点菜" android:textColor="@android:color/black" /> <TextView android:id="@+id/tv_discuss" style="@style/tvNavigationBarStyle" android:layout_toRightOf="@id/tv_order" android:text="评价" android:textColor="@color/dark_gray" /> <TextView android:id="@+id/tv_business" style="@style/tvNavigationBarStyle" android:layout_toRightOf="@id/tv_discuss" android:text="商家" android:textColor="@color/dark_gray" /> <TextView android:layout_width="70dp" android:layout_height="30dp" android:layout_alignParentRight="true" android:layout_marginRight="15dp" android:background="@drawable/friend_list" android:gravity="center" android:text="好友拼单" android:textColor="#ef842c" android:textSize="12sp" /> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <fragment android:id="@+id/left" android:name="cn.itcast.menu.LeftFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" tools:layout="@layout/left_layout" /> <fragment android:id="@+id/right" android:name="cn.itcast.menu.RightFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="3" tools:layout="@layout/right_layout" /> </LinearLayout> </LinearLayout> left_layout.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="match_parent" android:background="#f7f8f9" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/tv_recommend" style="@style/tvLeftStyle" android:text="推荐" android:background="@android:color/white"/> <TextView android:id="@+id/tv_must_buy" style="@style/tvLeftStyle" android:text="进店必买" /> </LinearLayout> list_item.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="match_parent" android:orientation="horizontal" android:padding="4dp"> <ImageView android:id="@+id/iv_img" android:layout_width="70dp" android:layout_height="70dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:orientation="vertical"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="2dp" android:textColor="@android:color/black" android:textSize="14sp" /> <TextView android:id="@+id/tv_sale" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#868788" android:textSize="12sp" /> <TextView android:id="@+id/tv_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:textColor="#e85b4d" android:textSize="12sp" /> </LinearLayout> </LinearLayout> right_layout.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="match_parent" android:background="@android:color/white" android:orientation="vertical"> <ListView android:id="@+id/lv_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@null"/> </LinearLayout> FoodBean.java package cn.itcast.menu; import java.io.Serializable; public class FoodBean implements Serializable { //序列化时保持FoodBean类版本的兼容性 private static final long serialVersionUID = 1L; private String name; //菜品名称 private String sales; //月售信息 private String price; //菜品价格 private int img; //菜品图片 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSales() { return sales; } public void setSales(String sales) { this.sales = sales; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public int getImg() { return img; } public void setImg(int img) { this.img = img; } } LeftFragment.java import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class LeftFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view =inflater.inflate(R.layout.left_layout,container,false); return view; } @Override public void onPause() { super.onPause(); } } RightAdapter.java import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.List; public class RightAdapter extends BaseAdapter { private Context mContext; private List<FoodBean> list; public RightAdapter(Context context ,List<FoodBean> list) { this.mContext = context; this.list=list; } @Override public int getCount() { //获取列表条目的总数 return list.size(); //返回ListView 条目的总数 } @Override public Object getItem(int position) { return list.get(position); //返回列表条目的数据对象 } @Override public long getItemId(int position) { return position; //返回列表条目的id } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = View.inflate(mContext, R.layout.list_item, null); holder = new ViewHolder(); holder.tv_name = convertView.findViewById(R.id.tv_name); holder.tv_sale = convertView.findViewById(R.id.tv_sale); holder.tv_price = convertView.findViewById(R.id.tv_price); holder.iv_img = convertView.findViewById(R.id.iv_img); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } FoodBean bean=list.get(position); holder.tv_name.setText(bean.getName()); holder.tv_sale.setText(bean.getSales()); holder.tv_price.setText(bean.getPrice()); holder.iv_img.setBackgroundResource(bean.getImg()); return convertView; } class ViewHolder { TextView tv_name, tv_sale,tv_price; ImageView iv_img; } } RightFragment.java import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import java.io.Serializable; import java.util.List; public class RightFragment extends Fragment { private ListView lv_list; public RightFragment() { } public RightFragment getInstance(List<FoodBean> list) { RightFragment rightFragment = new RightFragment(); //通过Bundle对象传递数据可以保证在设备横竖屏切换时传递的数据不丢失 Bundle bundle = new Bundle(); //将需要传递的字符串以键值对的形式传入bundle对象 bundle.putSerializable("list", (Serializable) list); rightFragment.setArguments(bundle); return rightFragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.right_layout, container, false); lv_list = view.findViewById(R.id.lv_list); if (getArguments() != null) { List<FoodBean> list = (List<FoodBean>) getArguments(). getSerializable("list"); RightAdapter adapter = new RightAdapter(getActivity(), list); lv_list.setAdapter(adapter); } return view; } } MainActivity.java import android.app.FragmentManager; import android.app.FragmentTransaction; import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.TextView; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { private FragmentManager fragmentManager; private FragmentTransaction fragmentTransaction; private LeftFragment leftFragment; private TextView tv_recommend, tv_must_buy; private RightFragment rightFragment; //推荐菜单列表数据 private String[] names1 = {"爆款*肥牛鱼豆腐骨肉相连三荤五素一份米饭", "豪华双人套餐", "【热销】双人套餐(含两份米饭)"}; private String[] sales1 = {"月售520 好评度80%", "月售184 好评度68%", "月售114 好评度60%"}; private String[] prices1 = {"¥23", "¥41", "¥32"}; private int[] imgs1 = {R.drawable.recom_one, R.drawable.recom_two, R.drawable.recom_three}; //进店必买菜单列表数据 private String[] names2 = {"'蔬菜主义'1人套餐", "2人经典套餐", "3人经典套餐"}; private String[] sales2 = {"月售26 好评度70%", "月售12 好评度50%", "月售4 好评度40%"}; private String[] prices2 = {"¥44", "¥132", "¥180"}; private int[] imgs2 = {R.drawable.must_buy_one, R.drawable.must_buy_two, R.drawable.must_buy_three}; private Map<String,List<FoodBean>> map; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setData(); init(); clickEvent(); } private void init() { fragmentManager = getFragmentManager();//获取fragmentManager //通过findFragmentById()方法获取leftFragment leftFragment = (LeftFragment) fragmentManager.findFragmentById(R.id.left); //获取左侧菜单栏中的控件 tv_recommend = leftFragment.getView().findViewById(R.id.tv_recommend); tv_must_buy = leftFragment.getView().findViewById(R.id.tv_must_buy); } private void setData(){ map=new HashMap<>(); List<FoodBean> list1=new ArrayList<>(); List<FoodBean> list2=new ArrayList<>(); for (int i=0;i<names1.length;i++){ FoodBean bean=new FoodBean(); bean.setName(names1[i]); bean.setSales(sales1[i]); bean.setPrice(prices1[i]); bean.setImg(imgs1[i]); list1.add(bean); } map.put("1",list1);//将推荐菜单列表的数据添加到map集合中 for (int i=0;i<names2.length;i++){ FoodBean bean=new FoodBean(); bean.setName(names2[i]); bean.setSales(sales2[i]); bean.setPrice(prices2[i]); bean.setImg(imgs2[i]); list2.add(bean); } map.put("2",list2); //将进店必买菜单列表的数据添加到map集合中 } private void clickEvent() { tv_recommend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //调用switchData()方法填充Rightfragment中的数据 switchData(map.get("1")); tv_recommend.setBackgroundColor(Color.WHITE); tv_must_buy.setBackgroundResource(R.color.gray); } }); tv_must_buy.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { switchData(map.get("2")); tv_must_buy.setBackgroundColor(Color.WHITE); tv_recommend.setBackgroundResource(R.color.gray); } }); //设置首次进入界面后,默认需要显示的数据 switchData(map.get("1")); } /** * 填充Activity右侧的Fragment,并传递列表数据list */ public void switchData(List<FoodBean> list) { fragmentManager = getFragmentManager(); fragmentTransaction = fragmentManager.beginTransaction();//开启一个事务 //通过调用getInstance()方法实例化RightFragment rightFragment = new RightFragment().getInstance(list); //调用replace()方法 fragmentTransaction.replace(R.id.right, rightFragment); fragmentTransaction.commit(); } } 说明如何编写列表显示的代码
最新发布
11-08
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值