【Android】在Fragment中使用ListView
2019-07-30 本文已影响0人
感同身受_
今天遇到在搬之前代码的时候,需要将我写在一个活动中的ListView写到Fragment中,但是,在我要搬完的时候,我的LayoutInflater出问题了,
一、自己所遇到的问题的分析过程
因为自己刚开始用的自定义Adapter,所以建了一个类去继承BaseAdAapter,并重写了四个方法,其中getView中的代码
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
Holder holder;
if(convertView == null){
Log.d("Flag","getView11");
convertView = LayoutInflater.from(SecondActivity.this).inflate(R.layout.my_adapter_item,null);
holder = new Holder();
holder.image = convertView.findViewById(R.id.image);
holder.name = convertView.findViewById(R.id.name);
holder.next = convertView.findViewById(R.id.next);
convertView.setTag(holder);
}else{
holder = (Holder) convertView.getTag();
}
holder.image.setImageResource((Integer) list.get(position).get("img"));
holder.name.setText((String) list.get(position).get("name"));
holder.next.setImageResource((Integer) list.get(position).get("next"));
Log.d("Flag","getView over");
return convertView;
}
}
class Holder{
private ImageView image;
private TextView name;
private ImageView next;
}
convertView = LayoutInflater.from(SecondActivity.this).inflate(R.layout.my_adapter_item,null);
就是这句,先说LayoutInflater.from(SecondActivity.this)
这个方法,
- from接收的参数是一个Context,不能放Fragment
- 这个方法返回值是一个inflater
后面的.inflate(R.layout.my_adapter_item,null)
,接收的是你要映射的布局,和一个root,
刚开始我想通过在Fragment中
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mine,container,false);
//list为保存数据的列表
MyAdapter adapter = new MyAdapter(list,inflater);
// MyAdapter adapter = new MyAdapter(list,inflater);
return inflater.inflate(R.layout.fragment_mine,container,false);
}
MyAdapter adapter = new MyAdapter(list,inflater)
;通过构造方法将inflater传进去直接调用.inflate(R.layout.my_adapter_item,null)
,但是运行后,并没有想要的结果
或者是用MyAdapter adapter = new MyAdapter(list,getActivity());
将Context传过去,但是发现结果都一样,都是下面的问题:
后面debug发现是因为Fragment中的onCreateView方法中的参数@NonNull LayoutInflater inflater,
是MainActivity中的inflater,但是我想要的是Fragment的inflater,所以结果不理想
二、解决办法
后面百度了“在Fragment中使用ListView”,才解决了我的问题
- 首先,你的ListView控件的id必须为
android:id="@android:id/list"
,在网上也看到过说android:id="@id/android:list"
这样的写法,但是我一写就报错 - 让你的Fragment继承ListFragment,这样你就能在你的Fragment中使用
setListAdapter(adapter);
方法, - 将你的适配器改用 SimpleAdapter
//参数一:上下文对象 参数二:数据源List<Map<String,Object>> 参数三:item对应的布局文件
//参数四:表示由map中定义的key组成的字符串类型的数字 参数五:需要显示的控件id组成的的数组
//保证参数四和参数五一一对应,否则控件属性会对换(张冠李戴)
adapter = new SimpleAdapter(getActivity(), getData(images, names),
R.layout.setting_adapter_item, new String[] { "img", "name","next" },
new int[] { R.id.image, R.id.name,R.id.next });
三、最终代码:
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import com.example.familyeducationhelp.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class mine extends ListFragment {
private ListView lv;
private SimpleAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//图片
int[] images = {R.drawable.news,R.drawable.record,R.drawable.setting};
//内容
String[] names = {"消息中心","家教记录","设置"};
//参数一:上下文对象 参数二:数据源List<Map<String,Object>> 参数三:item对应的布局文件
//参数四:表示由map中定义的key组成的字符串类型的数字 参数五:需要显示的控件id组成的的数组
//保证参数四和参数五一一对应,否则控件属性会对换(张冠李戴)
adapter = new SimpleAdapter(getActivity(), getData(images, names),
R.layout.setting_adapter_item, new String[] { "img", "name","next" },
new int[] { R.id.image, R.id.name,R.id.next });
//继承了ListFragment后的方法
setListAdapter(adapter);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mine,container,false);
lv = view.findViewById(android.R.id.list);
return inflater.inflate(R.layout.fragment_mine,container,false);
}
//监听点击事件
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
if(position == 0){
Toast.makeText(getActivity(),"你点击了 消息中心",Toast.LENGTH_LONG).show();
}else if(position == 1){
Toast.makeText(getActivity(),"你点击了 家教记录",Toast.LENGTH_LONG).show();
}else if(position == 2){
Toast.makeText(getActivity(),"你点击了 设置",Toast.LENGTH_LONG).show();
}
super.onListItemClick(l, v, position, id);
}
//对数据进行加载
private List<? extends Map<String, ?>> getData(int[] images, String[] names) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
for (int i = 0; i < images.length; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("img", images[i]);
map.put("name", names[i]);
map.put("next",R.drawable.next);
list.add(map);
}
return list;
}
}
布局中的代码:
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/guideline_Listview"
app:layout_constraintTop_toTopOf="@+id/guideline_Listview_Top"
tools:layout_editor_absoluteX="0dp"/>