Jake Wharton 的 LinePageIndicator 在视图回收后不会重新启动

Posted

技术标签:

【中文标题】Jake Wharton 的 LinePageIndicator 在视图回收后不会重新启动【英文标题】:Jake Wharton's LinePageIndicator does not restart after a view recycles 【发布时间】:2016-03-26 17:35:30 【问题描述】:

ListView 适配器有问题。我正在尝试开发一个简单的时间线视图。我决定为此使用ListViewBaseAdapter,以便有效地在垂直行中显示项目。一切似乎都很好,但是重用用于可视化列表中项目的视图存在问题。每个项目都有三个TextView(标题、详细信息和故事),ViewPager 用于显示照片,而 Jake Wharton 的LinePageIndicator 用于显示其中有多少张照片以及当前显示了哪些。

ViewPager 中始终加载正确的图片,它们从左向右滑动,但指示器无法正常工作。有时会显示有两张照片,尽管只有一张(这是因为之前的视图有两张照片),并且它没有显示ViewPager 中的第一张照片当前呈现。它显示上一个视图中ViewPager 中的最后一个当前位置。

显然指示器存在问题,每次视图回收时都应该以某种方式重新启动它。我已经查看了LinePageIndicator 源代码,发现setViewPager(...) 方法有这个

if (mViewPager != null) 
    //Clear us from the old pager.
    mViewPager.setOnPageChangeListener(null);

但显然它没有帮助......

最后是我的 getView(...) 方法

...
@Override
    public View getView(int position, View convertView, ViewGroup parent) 

        TextView txtTimelineItemTitle;
        TextView txtTimelineItemDetails;
        TextView txtTimelineItemText;
        ViewPager viewPager;
        LinePageIndicator indicator;

        if (convertView == null) 
            convertView = LayoutInflater.from(context)
                    .inflate(R.layout.timeline_item, parent, false);
            txtTimelineItemTitle = (TextView) convertView.findViewById(R.id.timeline_item_title);
            txtTimelineItemDetails = (TextView) convertView.findViewById(R.id.timeline_item_details);
            txtTimelineItemText = (TextView) convertView.findViewById(R.id.timeline_item_text);
            viewPager = (ViewPager) convertView.findViewById(R.id.timeline_view_pager);
            indicator = (LinePageIndicator) convertView.findViewById(R.id.indicator);
            convertView.setTag(new ViewHolder(context, txtTimelineItemTitle, txtTimelineItemDetails, txtTimelineItemText, viewPager, indicator));
         else 
            ViewHolder viewHolder = (ViewHolder) convertView.getTag();
            txtTimelineItemTitle = viewHolder.txtTimelineItemTitle;
            txtTimelineItemDetails = viewHolder.txtTimelineItemDetails;
            txtTimelineItemText = viewHolder.txtTimelineItemText;
            viewPager = viewHolder.viewPager;
            indicator = viewHolder.indicator;
        

        Story story = (Story) getItem(position);
        txtTimelineItemTitle.setText(story.getTitle());
        txtTimelineItemDetails.setText(Utils.dateFormat.format(stories.get(position).getDate()) + ", " + stories.get(position).getLocation());
        txtTimelineItemText.setText(story.getText());

        if (story.getImages().isEmpty()) 
            viewPager.setVisibility(View.GONE);
            indicator.setVisibility(View.GONE);
         else 
            viewPager.setVisibility(View.VISIBLE);
            indicator.setVisibility(View.VISIBLE);

            ImageAdapter imageAdapter = new ImageAdapter(context);
            imageAdapter.updateImages(story.getImages());
            viewPager.setAdapter(imageAdapter);
            indicator.setViewPager(viewPager);
        

        return convertView;
    
...

你们中有人遇到过这样的问题吗?怎么解决?如果没有,是否有替代方案?

非常感谢

【问题讨论】:

【参考方案1】:

因为这对我来说非常重要,所以我继续探索LinePageIndicator 的源代码。我已经看到除了setViewPager(ViewPager viewPager) 方法之外,还有setViewPager(ViewPager view, int initialPosition) 方法,如您所见,它允许您在ViewPager 中设置当前项目。我在上面的代码中只更改了一行 它解决了我的问题。

indicator.setViewPager(viewPager, 0); //always start from the first item in the ViewPager

【讨论】:

以上是关于Jake Wharton 的 LinePageIndicator 在视图回收后不会重新启动的主要内容,如果未能解决你的问题,请参考以下文章

Jake Wharton 的 LinePageIndicator 在视图回收后不会重新启动

因为 GitHub Actions 我发现了 Jake Wharton 的一个仓库

python基础:我家狗Jake——常用的简单数据类型

KMP算法学习记录----Jake Boxer博文学习部分

分享《Python数据科学手册》+PDF+源码+Jake VanderPlas+陶俊杰

C开发系列-字符串