在可扩展列表视图中聚焦添加的项目

4
这似乎很简单,但我却想不出来。
我有一个ExpandableListView,自定义的ExpandableListAdapter是从BaseExpandableListAdapter派生的。当我添加一个新项目时,我只想聚焦在新项目上。但我不能让它工作。
我尝试了以下操作,但没有成功。这是在拥有listview的活动中:
private void processNewItem(C360ItemOwner itemOwner, int pos){
    Item item = itemOwner.newItem(pos);
    expAdapter.notifyDatasetChanged();
    expandList.requestFocus();
    if (item.getParentType() == Item.PARENT_IS_CHECKLIST) {//main level
        expandList.setSelectedGroup(pos);
    } else //Item.PARENT_IS_ITEM //sub level
        expandList.setSelectedChild(item.getParentAsItem().getPosition(), pos, true);
}

我尝试在getView方法的适配器中处理它,但是不起作用:

public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
        ViewGroup parent) {
    if (convertView == null)
        convertView = inf.inflate(R.layout.edit_group_item, null);
    Item group = (Item) getGroup(groupPosition);
    convertView.setTag(group);
    EditText edtParent = (EditText) convertView.findViewById(R.id.edtParent);
    edtParent.setTag(convertView);
    scatterItemText(edtParent);
    if (group.isNew()) {
        Toast.makeText(edtParent.getContext(), "Found Focus Item " + groupPosition, Toast.LENGTH_SHORT).show();
        edtParent.requestFocus();
    }
    return convertView;
}

我尝试在适配器中设置了两个字段:focusItem(一个只写的Item对象)和focusEdit(一个只读的EditText对象)。我将Item分配给它,然后在getView方法中存储该编辑字段。调用方式如下:

private void processNewItem(C360ItemOwner itemOwner, int pos){
    Item item = itemOwner.newItem(pos);
    expAdapter.setFocusItem(item);//<--Assign it here
    expAdapter.notifyDatasetChanged();
    EditText edtFocus = expAdapter.getFocusEdit();
    if (edtFocus != null)
        edtFocus.requestFocus();

}

然后在适配器的getView方法中:

public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
        ViewGroup parent) {
    if (convertView == null)
        convertView = inf.inflate(R.layout.edit_group_item, null);
    Item group = (Item) getGroup(groupPosition);
    convertView.setTag(group);
    EditText edtParent = (EditText) convertView.findViewById(R.id.edtParent);
    edtParent.setTag(convertView);
    scatterItemText(edtParent);
    if (group == focusItem) {
        Toast.makeText(edtParent.getContext(), "Found Focus Item " + groupPosition, Toast.LENGTH_SHORT).show();
        focusEdit = edtParent;
    }
    return convertView;
}

我对这个方法很有希望,但是这一行代码:
EditText edtFocus = expAdapter.getFocusEdit();

在getView()方法运行之前发生,此时尚未指定它(因此它始终为空)! :-( 请帮忙

编辑:我知道这很笨拙,但如果我运行一个线程等待几百毫秒,以便getView()可能运行,然后尝试获取focusEdit怎么办?


1
你不需要像那样使用线程来暂停。看一下 Handler.postDelayed(Runnable r, int delay); - FoamyGuy
1
我尝试了以下方法,但它不起作用。为什么它不起作用?不要进入Adapter getView方向。 - Tomer Mor
@Tomer 对不起,我不太明白。能否请您再解释一下?感谢你们两位。 - Geeks On Hugs
1
请解释为什么第一个场景不起作用,我相信第一个场景是解决方案。 - Tomer Mor
我不确定,但它似乎无法正确聚焦视图?我不知道为什么它不起作用,但是我使用处理器成功地使其工作,并将其发布为答案。非常感谢。等我有时间时,我会仔细研究并尝试弄清楚为什么第一个没有起作用,并在此回复。 - Geeks On Hugs
1个回答

0

好的,通过Foamy Guy的帮助,我解决了问题。我的直觉是等待一段时间来检查focusEdit是否可用,这个想法很正确。我最初尝试使用1000毫秒来确保有足够的时间:

private void setFocus() {
    EditText edtFocus = expAdapter.getFocusEdit();
    if (edtFocus != null)
        edtFocus.requestFocus();
    else
        Toast.makeText(getActivity(), "BLAH!", Toast.LENGTH_SHORT).show();
}

final Runnable r = new Runnable()
{
    public void run() 
    {
        setFocus();

    }
};

private void processNewItem(C360ItemOwner itemOwner, int pos){
    Item item = itemOwner.newItem(pos);
    if (itemOwner.getItemCount() == 1)
        checkHasItems();
    expAdapter.setFocusItem(item);
    resetListAdapter(true);
    Handler handler = new Handler();
    handler.postDelayed(r, 1000);//this works
    //handler.postDelayed(r, 10);//this works too
    //handler.postDelayed(r, 1);//this works too
    //handler.post(r);//this too!
    //r.run();//NOT this.  This fails.
}

然后我尝试了10毫秒,它仍然有效。 然后只有1毫秒,令人惊讶的是那也起作用了。 Foamy建议尝试不使用延迟直接发布,确实有效。 最后,我按照Foamy的要求直接运行了可运行文件,但失败了。

所以不确定,但这可以完成工作。 感谢大家的帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接