在ExpandableListView中设置倒数计时器-回收问题 [英] Setting Countdown Timer in ExpandableListView - Recycling Issue

查看:77
本文介绍了在ExpandableListView中设置倒数计时器-回收问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我以前写过这个问题,但是从那以后缩小了问题的范围,因此决定重写它.我想做的是在ExpandableListView的每个组中设置一个倒数计时器.现在,我通过在模型对象中开始每个倒数计时来执行此操作,然后在向每个组充气时获得该项目的剩余时间,并将其传递给适配器中的新倒数计时器实例.除了当我展开一个子列表并将某些父组滚动到远离屏幕的位置以回收它们时,所有这些工作都非常完美.重新创建它们后,所有视图均已正确设置,但包含倒计时的文本视图除外,此视图将切换.因此,我看到的是两个或多个倒计时错误的组.这些组仍然是有序的,并且模型对象仍然是正确的.因此,我的具体问题有两个:1.是否有更好的方法来实现我要实现的目标? 2.是否会因为我正在访问设置内部类倒数计时的textview而发生这种情况?我最初以为这个问题与可扩展列表返回错误的viewGroup有关,现在我不确定.

Okay, I previously wrote this question, but have narrowed the problem down since then so decided to rewrite it. What I am trying to do is set a Countdown Timer in each group in ExpandableListView. Right now I do this by starting each countdown in my model object, then when I inflate each group I get the remaining time for that item and pass it to a new instance of countdown timer in the adapter. This all works perfectly except when I expand a child list and scroll some of the parent groups far off the screen to where they are recycled. When they are recreated, all of the views are set correctly except for the textview containing the countdown, this one switches. So what I see are two or more groups with the wrong countdown. The groups are still in order and the model object is still the correct one. So my specific questions are two: 1. Is there a better way to achieve what I am trying to accomplish? 2. Could this be happening because I am accessing the textview that sets the countdown from an inner class? I originally thought this problem had something to do with expandable list returning the wrong viewGroup, now I am not so sure.

@Override
public View getGroupView(int groupPosition, final boolean isExpanded, View convertView, final ViewGroup parent) {

    final GroupViewHolder groupViewHolder;



    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.item_lobby, null);
        groupViewHolder = new GroupViewHolder();
        convertView.setTag(groupViewHolder);


    }else{

        groupViewHolder = (GroupViewHolder) convertView.getTag();

    }

    groupViewHolder.lobbyItemExpandIndicator = (ImageView) convertView.findViewById(R.id.lobbyItemExpandIndicator);
    groupViewHolder.gameType = (TextView) convertView.findViewById(R.id.lobbyGameType);
    groupViewHolder.accepting = (TextView) convertView.findViewById(R.id.lobbyAccepting);
    groupViewHolder.gamesInDraft = (TextView) convertView.findViewById(R.id.lobbyGamesInDraft);
    groupViewHolder.mContestItem = (ContestItem) getGroup(groupPosition);
    groupViewHolder.draftCloses = groupViewHolder.mContestItem.getDraftCloses();


        if (groupViewHolder.draftCountdownTimer == null) {
            groupViewHolder.draftEnding = (TextView) convertView.findViewById(R.id.lobbyDraftEnding);

            groupViewHolder.draftCountdownTimer = new CountDownTimer(groupViewHolder.draftCloses, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    long durationSeconds = millisUntilFinished / 1000;

                    groupViewHolder.draftEnding.setText((String.format(Locale.ENGLISH, "%02d:%02d:%02d", durationSeconds / 3600,
                            (durationSeconds % 3600) / 60, (durationSeconds % 60))));
                }

                @Override
                public void onFinish() {
                    groupViewHolder.draftEnding.setText("Draft Finished");
                }
            }.start();
        }


    groupViewHolder.gameType.setText(groupViewHolder.mContestItem.getGameType());
    groupViewHolder.accepting.setText(groupViewHolder.mContestItem.getAccepting());
    groupViewHolder.gamesInDraft.setText(groupViewHolder.mContestItem.getNbaGamesAmnt());

    if (isExpanded) {
        groupViewHolder.lobbyItemExpandIndicator.setImageResource(R.drawable.w_dash);
    } else {
        groupViewHolder.lobbyItemExpandIndicator.setImageResource(R.drawable.w_down);
    }

    return convertView;
}

public class GroupViewHolder {

    TextView draftEnding;
    TextView gameType;
    TextView accepting;
    TextView gamesInDraft;
    ImageView lobbyItemExpandIndicator;
    CountDownTimer draftCountdownTimer;
    ContestItem mContestItem;
    long draftCloses;

}

推荐答案

我再重复一遍,您再次从Viewholder,View Holder中获取项目-阅读这两个词并尝试理解它们:

I repeat one more time, you again get item from viewholder, view holder - read this two words and try to understand them:

1)Viewholder用于保存视图,这意味着它用于保存诸如findViewById之类的操作的结果(这对于应用程序而言是繁重的操作).

1) viewholder is for hold views, this mean it's for to hold results for such operations as findViewById (this is heavy operation for app).

2)视图持有者重用视图,不要将与项目相关的信息保留在列表中,仅用于视图!因为如果您将信息存储在下一个滚动条中,则它的查看器可能包含其他项的信息.

2) viewholder reuses views, DON'T keep information that is related to item in list, it's only for views! Coz if you store info in next your scroll it viewholder can contain information from another item.

3)所有数据信息(包括倒计时)都必须保留在项目模型中,就在您的哈希图中,并且必须以正确的方式在onBindViewholder中从中还原.

3) all data information, including countdowns must be hold in item model, right in your hashmap and must be restored from it in onBindViewholder only in this way is the right way.

以下是我的代码中的示例方法:

here is sample how to do it from my code:

在您定义的适配器中:

private HashMap<CategoryModel, List<CategoryModel>> mMainMenuExpandableList; // This is your categories;
private List<CategoryModel> mMainMenuKeysList; // This is your keys to be easier already in separated list;

在构造函数中,您可以设置以下值:

in constructor you set this values:

public CategoriesExpandableListAdapter(HashMap<CategoryModel, List<CategoryModel>> hashMap, List<CategoryModel> keyList){
    mMainMenuExpandableList = hashMap;
    mMainMenuKeysList = keyList;
}

然后覆盖getGroupgetChild:

@Override
public Object getGroup(int groupPosition) {
    return mMainMenuKeysList.get(groupPosition);
}

@Override
public Object getChild(int groupPosition, int childPosition) {
    return mMainMenuExpandableList.get(mMainMenuKeysList.get(groupPosition)).get(childPosition);
}

然后在getGroupView中:

final CategoryModel groupObject = (CategoryModel) getGroup(groupPosition);

getChildView中,您可以使两个对象都起作用:

in getChildView you can get both objects to act:

CategoryModel groupObject = (CategoryModel) getGroup(groupPosition);
CategoryModel childObject = (CategoryModel) getChild(groupPosition,childPosition);

现在,当您从哈希中获取适当的对象类别时,您可以从该对象中获取倒数并显示它们.

and now when you got proper object from hash for category you can get from that object your countdowns and display them.

希望这会有所帮助, 祝你有美好的一天:)

Hope this will help, Have a nice day :)

这篇关于在ExpandableListView中设置倒数计时器-回收问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆