PagerAdapter 的问题
Posted
技术标签:
【中文标题】PagerAdapter 的问题【英文标题】:Issue with PagerAdapter 【发布时间】:2017-10-11 09:48:37 【问题描述】:我尝试从 firebase 数据库加载数据库并得到这个异常。这是关于notifyDataSetChanged
。我试图在SlideShowAapter
中输入getCount()
,但它没有奏效。
例外:
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged!
Expected adapter item count: 0, found: 1 Pager id: com.example.dave.lomoapp:id/slideShow Pager class: class android.support.v4.view.ViewPager
Problematic adapter: class com.example.davenguyen.lomoapp.SlideShowAdapter
at android.support.v4.view.ViewPager.populate(ViewPager.java:1135)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:662)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:624)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:616)
at com.example.davenguyen.lomoapp.HomeFragment$1.run(HomeFragment.java:71)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
这是我的 SlideShowAdapter
public class SlideShowAdapter extends PagerAdapter
private boolean doNotifyDataSetChangedOnce = false;
private ArrayList<Genre> genresList;
private LayoutInflater inflater;
private Context context;
public SlideShowAdapter(Context context, ArrayList<Genre> images)
this.context = context;
this.genresList =images;
inflater = LayoutInflater.from(context);
@Override
public void destroyItem(ViewGroup container, int position, Object object)
container.removeView((View) object);
@Override
public int getCount()
if (doNotifyDataSetChangedOnce)
doNotifyDataSetChangedOnce = false;
notifyDataSetChanged();
return genresList.size();
@Override
public Object instantiateItem(ViewGroup view, int position)
View myImageLayout = inflater.inflate(R.layout.slide, view, false);
ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.slideShowImg);
Picasso.with(context).load(genresList.get(position).getImage()).into(myImage);
view.addView(myImageLayout, 0);
view.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
);
return myImageLayout;
@Override
public boolean isViewFromObject(View view, Object object)
return view.equals(object);
这是一个包含我的自定义适配器的片段
public class HomeFragment extends Fragment
private static ViewPager mPager;
private static int currentPage = 0;
private ArrayList<Genre> genreList = new ArrayList<Genre>();
DatabaseReference mref;
public HomeFragment()
// Required empty public constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Inflate the layout for this fragment
View v =inflater.inflate(R.layout.fragment_home, container, false);
return v;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
loadImage();
mPager = (ViewPager) view.findViewById(R.id.slideShow);
mPager.setAdapter(new SlideShowAdapter(getActivity(), genreList));
CircleIndicator indicator = (CircleIndicator) view.findViewById(R.id.indicator);
indicator.setViewPager(mPager);
// Auto start of viewpager
final Handler handler = new Handler();
final Runnable Update = new Runnable()
public void run()
if (currentPage == genreList.size())
currentPage = 0;
mPager.setCurrentItem(currentPage++, true);
;
Timer swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask()
@Override
public void run()
handler.post(Update);
, 2500, 2500);
private void loadImage()
// Get a reference to our genres
mref = FirebaseDatabase.getInstance().getReference().child("genres");
// Attach a listener to read the data at our genres reference
mref.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(DataSnapshot dataSnapshot)
genreList.add (dataSnapshot.getValue(Genre.class));
@Override
public void onCancelled(DatabaseError databaseError)
Log.i("READ_FAIELD","The read failed: " + databaseError.getCode());
);
提前致谢
【问题讨论】:
调用 adapter.notifydatasetchanged();填写数据后 【参考方案1】:我的猜测是问题在于适配器中的标志doNotifyDataSetChangedOnce
。尝试删除 if
并在加载图像后调用 adapter.notifyDataSetChanged()
(在 onDataChange
中)。
如果这解决了崩溃但 viewPager 没有更新,您可能需要在适配器中添加以下代码:
public int getItemPosition(Object object)
return POSITION_NONE;
【讨论】:
你是救生员。但是,它在将代码分开后可以工作,如@Divyesh Patel 所示 添加public int getItemPosition(Object object) return POSITION_NONE;
后不更新
你在哪里调用 notifyDataSetChanged?
@DonDave 如果您在将新项目添加到 arrayList 之后删除它并移动 notifyDataSetChanged 它应该可以工作。【参考方案2】:
这样写:
SlideShowAdapter adapter=new SlideShowAdapter(getActivity(), genreList);
mPager.setAdapter(adapter);
adapter.notifyDataSetChanged();
代替
mPager.setAdapter(new SlideShowAdapter(getActivity(), genreList));
尝试用这个来改变instanceiteItem:
View myImageLayout = inflater.inflate(R.layout.slide, view, false);
ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.slideShowImg);
Picasso.with(context).load(genresList.get(position).getImage()).into(myImage);
.
myImageLayout.addView(myImage, 0);
myImageLayout.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
);
return myImageLayout;
并删除:
if (doNotifyDataSetChangedOnce)
doNotifyDataSetChangedOnce = false;
notifyDataSetChanged();
【讨论】:
这一行得到错误 "cant resolve method addView "myImageLayout.addView(myImage, 0);
从方法中移除 0以上是关于PagerAdapter 的问题的主要内容,如果未能解决你的问题,请参考以下文章
在使用 PagerAdapter 和 ViewPager 中的选项卡之间滑动时出现问题