Despite the title of this question, its content is quite different.
In my Activity
I want to represent data both with a GridView
and a ListView
. I created two Button
s that when clicked hide one of the View
s and shows the other:
//onClick
//switch(view.getId())
case R.id.itemselect_button_grid:
if (lv.getVisibility() == View.VISIBLE) {
lv.invalidate();
lv.setVisibility(View.GONE);
gv.setVisibility(View.VISIBLE);
mAdapter.setIsListView(false);
mAdapter.notifyDataSetChanged();
gv.setAdapter(mAdapter);
}
break;
case R.id.itemselect_button_list:
if (gv.getVisibility() == View.VISIBLE) {
gv.invalidate();
gv.setVisibility(View.GONE);
lv.setVisibility(View.VISIBLE);
mAdapter.setIsListView(true);
mAdapter.notifyDataSetChanged();
lv.setAdapter(mAdapter);
}
break;
I am using the same Adapter
to handle the items. I set a boolean
flag (setIsListview) that basically represents data in two different ways according to the parent View
.
public View getView(final int position, View v, ViewGroup parent) {
if (v == null) {
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
if (!isListView)
v = inflater.inflate(layId, parent, false);
else
v = inflater.inflate(R.layout.item_list_layout, parent,
false);
}
Item entry = Entries.getItems().get(position);
if (!isListView) {
NetworkImageView image = (NetworkImageView) v
.findViewById(R.id.item_cover);
//Line 70 is the following, image is null.
image.setImageDrawable(mContext.getResources().getDrawable(
Items.notFoundDrawables.get(categoryItem)));
image.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
image.setScaleType(ScaleType.FIT_XY);
image.getLayoutParams().width = image.getMeasuredWidth();
image.getLayoutParams().height = image.getMeasuredHeight();
image.setDefaultImageResId(GamesomePlatforms.notFoundDrawables.get(platform));
image.setErrorImageResId(GamesomePlatforms.notFoundDrawables.get(platform));
if (null != entry.getCoverURL()) {
image.setImageUrl(entry.getCoverURL(), mImageLoader);
}
}
TextView itemTitle = (TextView) v.findViewById(R.id.item_title);
itemTitle.setText(entry.getTitle());
return v;
}
logcat error:
02-21 11:01:12.216: E/AndroidRuntime(7587): FATAL EXCEPTION: main
02-21 11:01:12.216: E/AndroidRuntime(7587): Process: com.vektor.gamesome, PID: 7587
02-21 11:01:12.216: E/AndroidRuntime(7587): java.lang.NullPointerException
02-21 11:01:12.216: E/AndroidRuntime(7587): at com.vektor.myapp.domain.adapters.MyListAdapter.getView(MyListAdapter.java:70)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.widget.AbsListView.obtainView(AbsListView.java:2240)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.widget.ListView.makeAndAddView(ListView.java:1790)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.widget.ListView.fillSpecific(ListView.java:1337)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.widget.ListView.layoutChildren(ListView.java:1608)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4202)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.view.Choreographer.doCallbacks(Choreographer.java:574)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.view.Choreographer.doFrame(Choreographer.java:543)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.os.Handler.handleCallback(Handler.java:733)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.os.Handler.dispatchMessage(Handler.java:95)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.os.Looper.loop(Looper.java:136)
02-21 11:01:12.216: E/AndroidRuntime(7587): at android.app.ActivityThread.main(ActivityThread.java:5081)
02-21 11:01:12.216: E/AndroidRuntime(7587): at java.lang.reflect.Method.invokeNative(Native Method)
02-21 11:01:12.216: E/AndroidRuntime(7587): at java.lang.reflect.Method.invoke(Method.java:515)
02-21 11:01:12.216: E/AndroidRuntime(7587): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781)
02-21 11:01:12.216: E/AndroidRuntime(7587): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-21 11:01:12.216: E/AndroidRuntime(7587): at dalvik.system.NativeStart.main(Native Method)
When I am scrolling the GridView
and click to convert it to ListView
, nothing happens, but if I am scrolling the ListView
and click to convert it to GridView
, the app throws a NullPointerException
saying that the image
is null. Why does this happen if I've already invalidated the ListView
and made it invisible?
I found a solution.
In each of the onClick
cases, I added a line to set the Adapter
of the old View
to null. This interrupts pending operations on the old View
.
case R.id.items_button_grid:
if (lv.getVisibility() == View.VISIBLE) {
lv.invalidate();
lv.setAdapter(null);
lv.setVisibility(View.GONE);
mAdapter.setIsListView(false);
mAdapter.notifyDataSetChanged();
gv.setVisibility(View.VISIBLE);
gv.setAdapter(mAdapter);
}
break;
case R.id.items_button_list:
if (gv.getVisibility() == View.VISIBLE) {
gv.invalidate();
gv.setAdapter(null);
gv.setVisibility(View.GONE);
mAdapter.setIsListView(true);
mAdapter.notifyDataSetChanged();
lv.setVisibility(View.VISIBLE);
lv.setAdapter(mAdapter);
}
break;
A good decoupled and simple solution is to reuse your data inside adapter and not the adapter itself. Make 2 adapters for GridView and ListView but re-use the same DataSource for both the adapters. This way you can in future change the UI of any view without changing anything with other view.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.