尝试listview.getChildAt()时java.lang.NullPointerException
ListView具有正确的值:
public class FragmentTab1 extends SherlockFragment { ListView list; LazyAdapter adapter; @Override public void onViewCreated(View view, Bundle savedInstanceState) { list = (ListView) getActivity().findViewById(android.R.id.list); //also I tried view.findViewById(android.R.id.list) ............ adapter = new LazyAdapter(getActivity(), mSource); list.setAdapter(adapter); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ View rootView = inflater.inflate(R.layout.fragmenttab1, container, false); return rootView;
}
当我尝试:
@Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); //correct int itemCount = list.getCount(); // 10 ps as show Logcat if (R.id.save == id) { CheckBox cb; for(int i = itemCount - 1; i >= 0; i--) { cb = (CheckBox)list.getChildAt(i).findViewById(R.id.checkBox1); //Error here } } return true; }
XML:
// same id
和适配器是下一个:
public class LazyAdapter extends BaseAdapter { private Activity activity; ArrayList bitmapArray = new ArrayList(); private ArrayList mObjects; private static LayoutInflater inflater=null; public ImageLoader imageLoader; public LazyAdapter(Activity a, ArrayList mObjects1) { activity = a; mObjects = mObjects1; inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); imageLoader=new ImageLoader(activity.getApplicationContext()); } public int getCount() { return mObjects.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { Data item = mObjects.get(position); View vi=convertView; if(convertView==null) vi = inflater.inflate(R.layout.item_internet, null); TextView text=(TextView)vi.findViewById(R.id.title1); ImageView image=(ImageView)vi.findViewById(android.R.id.icon); text.setText(item.getmTitle()); bitmapArray.add(imageLoader.getBitmap()); imageLoader.DisplayImage(item.getmImageUrl(), image); return vi; }
我收到正确的ListView,但是当我尝试从操作栏单击“保存”按钮时收到错误。 可能,我应该在适配器中初始化CheckBox? 有人可以帮帮我吗?
如果子项不可见, list.getChildAt(i)
将为null。 因此在使用前请检查null。
因此,您无法以这种方式检索所有已检查的项目。
请发布完整的.xml和的定义。
我认为你会得到一个indexoutofbounds,但因为它是null,这可能是原因: ListView getChildAt为可见的孩子返回null
另外,在for循环中放置一个日志语句以显示所有相关变量的值,因此:i和itemCount等。
并在循环之前设置断点并运行调试模式以逐步检查值,因为它循环通过,你会看到我的值导致调试器中的nullpointer,或者如果你错过它,它将在logcat中
我知道这是很老的post。 但我正在回答,因为人们仍在寻找一个关于ListView getChildAt()null指针exception的解决方法。
这是因为ArrayApdater因为高度而正在REMOVING和RECYCLING ListView上尚未显示的视图。 因此,如果您有10个项目视图,并且ListView可以在当时显示4 – 5:
-
适配器删除位置5到9的项目视图,以便任何对
adapter.getChildAt(5... to 9)
尝试都将导致空指针exception -
适配器还可以循环项目视图,因此当您向下滚动到5到9时,您在位置3上所做的任何引用都将丢失,并且您在位置3(EditText,Checkbox等)上所做的任何输入都将丢失向下滚动到5到9时将被回收,并在以后的另一个位置(从位置1,2或3等)重新使用,具有相同的值
我发现控制它的唯一方法是忘记获取视图并拥有:
- 属性
HashMap
或您希望处理要用于列表中每个项目的值的任何类型。 对于cbValues item->getId()
或position
item->getId()
,第一种类型必须是唯一的。 在构造函数中使用新的HashMap<>()
初始化它; - 为输入视图添加InputListener,(为EditText添加addTextChangedListener,为Checkbox添加setOnCheckedChangeListener等)。在输入时,更新HashMap键(
item.getId()
或position
)和值(editable.toString()
或true
或false
)。 防爆。 on@Override public void onCheckedChanged
,put boolean resultcbValues.put(item.getId(), b);
-
防止适配器使用循环使用的convertView,删除条件
if(convertView == null)
以便适配器始终为全新的视图实例充气。 因为视图实例每次都是新的,所以每次都必须设置HashMap的值,就好像它已经包含密钥if(cbValues.containsKey(item.getId())){cbItem.setChecked(cbValue.get(cbItem.getId()))};
。 可能在这种情况下,没有大量的项目,因此平滑滚动不是必须的。 -
最后创建公共方法以获取Adapter之外的值传递
item->getId()
Integer作为参数。 例如:’public bool getCheckboxValueForItemId(int itemId){return cbValues.get(itemId); }。 然后从适配器中选择项目将很容易
这是最后的代码:
public class LazyAdapter extends BaseAdapter { private Activity activity; ArrayList bitmapArray = new ArrayList (); private ArrayList mObjects; private static LayoutInflater inflater=null; public ImageLoader imageLoader; HashMap cbValues; public LazyAdapter(Activity a, ArrayList mObjects1) { activity = a; mObjects = mObjects1; cbValues = new HashMap<>(); inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); imageLoader=new ImageLoader(activity.getApplicationContext()); } public int getCount() { return mObjects.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { Data item = mObjects.get(position); View vi=convertView; // Remove convertView condition //if(convertView==null) vi = inflater.inflate(R.layout.item_internet, null); TextView text=(TextView)vi.findViewById(R.id.title1); ImageView image=(ImageView)vi.findViewById(android.R.id.icon); Checkbox cbItem = (Checkbox) vi.findViewById(android.R.id.checkbox1); text.setText(item.getmTitle()); bitmapArray.add(imageLoader.getBitmap()); imageLoader.DisplayImage(item.getmImageUrl(), image); if(cbValues.containsKey(item.getId())) { cbItem.setChecked(cbValue.get(cbItem.getId()))}; } cbItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { cbValues.put(item.getId(), b); } }); return vi; } // itemId : unique identifier for an Item, not the position of Item in Adapter public bool getCheckboxValueForItemId(int itemId) { return cbValues.get(itemId); } }