ExpandableListView 中的自定义视图不会获取点击事件

发布于 2024-12-28 12:49:07 字数 6521 浏览 0 评论 0原文

我的活动中有一个 ExpandableListView,有两个组。每个组都有一个自定义视图。我可以单击每个组中的按钮并且它可以工作。如果我单击一组自定义视图中的文本字段,则会显示软键盘。但一旦我关闭它,两组中都不会记录任何点击。键盘关闭后,ExpanableListView 将失去焦点。对话框消失后,如何将焦点重新设置在列表视图上?如果我折叠并展开组,它会被重置。我尝试过各种监听器都没有效果。

我的类和布局有点复杂,但我将其剥离到最低限度,这是我的代码。

package com.test;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.*;
import android.widget.*;

public class TestOnClickActivity extends Activity
{
    private static final String cLogTag = "TestOnClick";

    private ExpadableAdapter iExpandableListAdapter;
    private ExpandableListView iExpandableList;
    private View[] iSearchViews;


    private class ExpadableAdapter extends BaseExpandableListAdapter 
    {
        private String[] iGroups = 
        {
            "Search By Device",
            "Search By Date",
        };

        @Override
        public Object getChild(int theGroupPosition, int theChildPosition)
        {
            return "NA";
        }

        @Override
        public long getChildId(int theGroupPosition, int theChildPosition)
        {
            return theGroupPosition;
        }

        @Override
        public int getChildrenCount(int theGroupPosition)
        {
            return 1;
        }

        @Override
        public View getChildView(int theGroupPosition, 
                                 int theChildPosition,
                                 boolean isLastChild, 
                                 View theConvertView, 
                                 ViewGroup theParent)
        {
            return iSearchViews[theGroupPosition];
        }

        @Override
        public Object getGroup(int theGroupPosition)
        {
            return iGroups[theGroupPosition];
        }

        @Override
        public int getGroupCount()
        {
            return iGroups.length;
        }

        @Override
        public long getGroupId(int theGroupPosition)
        {
            return theGroupPosition;
        }

        @Override
        public View getGroupView(int theGroupPosition, 
                                 boolean theIsExpanded,
                                 View theConvertView, 
                                 ViewGroup theParent)
        {
            if (theConvertView == null) {
                Context theContext = TestOnClickActivity.this;
                TextView theTV = new TextView(theContext, 
                                              null, 
                                              android.R.attr.textAppearanceMedium);
                theTV.setText(iGroups[theGroupPosition]);
                return theTV;

            } else {
                return theConvertView;  
            } 
        }

        @Override
        public boolean hasStableIds()
        {
            return true;
        }

        @Override
        public boolean isChildSelectable(int theGroupPosition,
                                         int theChildPosition)
        {
            return true;
        }
    }


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle theSavedState) 
    {
        super.onCreate(theSavedState);
        setContentView(R.layout.main);
        iExpandableListAdapter = new ExpadableAdapter();
        iExpandableList = 
                (ExpandableListView) findViewById(R.id.searchOptionsListView);
        iExpandableList.setAdapter(iExpandableListAdapter);
        iExpandableList.setGroupIndicator(null);
        createSearchViews();
    }

    private void createSearchViews()
    {
        iSearchViews = new View[2];
        LinearLayout theRowView;

        // Create the Search By Device View
        LayoutInflater theInflator = (LayoutInflater) getSystemService(
                                        Context.LAYOUT_INFLATER_SERVICE);
        theRowView = new LinearLayout(this);
        theInflator.inflate(R.layout.search1, theRowView, true);
        iSearchViews[0] = theRowView;

        // Create the Search By Date View
        theRowView = new LinearLayout(this);
        theInflator.inflate(R.layout.search2, theRowView, true);
        iSearchViews[1] = theRowView;
    }
}

布局文件是 main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ExpandableListView
        android:id="@+id/searchOptionsListView"
        android:divider="@android:color/transparent"        
        android:childDivider="#00000000"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ExpandableListView>

</LinearLayout>

search1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/searchByDeviceIdLinearLayout"
   android:paddingLeft="36dp"
   android:layout_width="match_parent"
   android:layout_height="wrap_content" 
   android:layout_marginBottom="5dp">

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginLeft="4dp"
       android:text="@string/deviceId"/>

   <EditText
       android:id="@+id/deviceIdEditText"
       android:layout_width="0dp"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:inputType="number" >
   </EditText>

  <ImageButton
       android:id="@+id/searchButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:contentDescription="@string/search"
       android:src="@drawable/ic_btn_search" />

</LinearLayout>

和 search2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchByDateLinearLayout"
    android:paddingLeft="36dp"      
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    android:layout_marginBottom="5dp">

   <ImageButton
       android:id="@+id/searchButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:contentDescription="@string/search"
       android:src="@drawable/ic_btn_search" />

</LinearLayout>

I have an ExpandableListView in my activity with two groups. Each group has a custom View. I can click on buttons in each group and it works. If I click on a text field in one group's custom view, the soft keyboard is displayed. But once I dismiss it, no clicks are registered in either group. The ExpanableListView loses focus after the keyboard is dismissed. How can I set the focus back on the list view once a dialog is dismissed? If I collapse and expand the groups, it gets reset. I have tried various listeners to no avail.

My class and layout are a little more complicated, but I stripped it off to the bare minimum and here is my code.

package com.test;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.*;
import android.widget.*;

public class TestOnClickActivity extends Activity
{
    private static final String cLogTag = "TestOnClick";

    private ExpadableAdapter iExpandableListAdapter;
    private ExpandableListView iExpandableList;
    private View[] iSearchViews;


    private class ExpadableAdapter extends BaseExpandableListAdapter 
    {
        private String[] iGroups = 
        {
            "Search By Device",
            "Search By Date",
        };

        @Override
        public Object getChild(int theGroupPosition, int theChildPosition)
        {
            return "NA";
        }

        @Override
        public long getChildId(int theGroupPosition, int theChildPosition)
        {
            return theGroupPosition;
        }

        @Override
        public int getChildrenCount(int theGroupPosition)
        {
            return 1;
        }

        @Override
        public View getChildView(int theGroupPosition, 
                                 int theChildPosition,
                                 boolean isLastChild, 
                                 View theConvertView, 
                                 ViewGroup theParent)
        {
            return iSearchViews[theGroupPosition];
        }

        @Override
        public Object getGroup(int theGroupPosition)
        {
            return iGroups[theGroupPosition];
        }

        @Override
        public int getGroupCount()
        {
            return iGroups.length;
        }

        @Override
        public long getGroupId(int theGroupPosition)
        {
            return theGroupPosition;
        }

        @Override
        public View getGroupView(int theGroupPosition, 
                                 boolean theIsExpanded,
                                 View theConvertView, 
                                 ViewGroup theParent)
        {
            if (theConvertView == null) {
                Context theContext = TestOnClickActivity.this;
                TextView theTV = new TextView(theContext, 
                                              null, 
                                              android.R.attr.textAppearanceMedium);
                theTV.setText(iGroups[theGroupPosition]);
                return theTV;

            } else {
                return theConvertView;  
            } 
        }

        @Override
        public boolean hasStableIds()
        {
            return true;
        }

        @Override
        public boolean isChildSelectable(int theGroupPosition,
                                         int theChildPosition)
        {
            return true;
        }
    }


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle theSavedState) 
    {
        super.onCreate(theSavedState);
        setContentView(R.layout.main);
        iExpandableListAdapter = new ExpadableAdapter();
        iExpandableList = 
                (ExpandableListView) findViewById(R.id.searchOptionsListView);
        iExpandableList.setAdapter(iExpandableListAdapter);
        iExpandableList.setGroupIndicator(null);
        createSearchViews();
    }

    private void createSearchViews()
    {
        iSearchViews = new View[2];
        LinearLayout theRowView;

        // Create the Search By Device View
        LayoutInflater theInflator = (LayoutInflater) getSystemService(
                                        Context.LAYOUT_INFLATER_SERVICE);
        theRowView = new LinearLayout(this);
        theInflator.inflate(R.layout.search1, theRowView, true);
        iSearchViews[0] = theRowView;

        // Create the Search By Date View
        theRowView = new LinearLayout(this);
        theInflator.inflate(R.layout.search2, theRowView, true);
        iSearchViews[1] = theRowView;
    }
}

The layout files are main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ExpandableListView
        android:id="@+id/searchOptionsListView"
        android:divider="@android:color/transparent"        
        android:childDivider="#00000000"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ExpandableListView>

</LinearLayout>

search1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/searchByDeviceIdLinearLayout"
   android:paddingLeft="36dp"
   android:layout_width="match_parent"
   android:layout_height="wrap_content" 
   android:layout_marginBottom="5dp">

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginLeft="4dp"
       android:text="@string/deviceId"/>

   <EditText
       android:id="@+id/deviceIdEditText"
       android:layout_width="0dp"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:inputType="number" >
   </EditText>

  <ImageButton
       android:id="@+id/searchButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:contentDescription="@string/search"
       android:src="@drawable/ic_btn_search" />

</LinearLayout>

and search2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchByDateLinearLayout"
    android:paddingLeft="36dp"      
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    android:layout_marginBottom="5dp">

   <ImageButton
       android:id="@+id/searchButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:contentDescription="@string/search"
       android:src="@drawable/ic_btn_search" />

</LinearLayout>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小…红帽 2025-01-04 12:49:07

在我看来,失去焦点的问题是另一个问题的结果。
您的适配器构造不正确。请注意,对于屏幕上显示的每个项目,它将传入 getChildView 和 getGroupView 方法。
这就是为什么每次单击该组时该组的名称都会更改的原因。

如果我在这些方法中添加一些日志,我可以看到:

01-24 11:18:02.575: D/TEST(443): > createSearchViews
01-24 11:18:02.715: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.715: D/TEST(443): > getGroupView : position=1
01-24 11:18:02.755: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.755: D/TEST(443): > getGroupView : position=1
01-24 11:18:02.845: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.845: D/TEST(443): > getGroupView : position=1
01-24 11:18:02.885: I/ActivityManager(59): Displayed activity com.test/.TestOnClickActivity: 455 ms (total 455 ms)
01-24 11:18:02.905: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.905: D/TEST(443): > getGroupView : position=1
01-24 11:18:08.246: D/TEST(443): > getGroupView : position=0
01-24 11:18:08.246: D/TEST(443): > getGroupView : position=1
01-24 11:18:08.246: D/TEST(443): > getChildView : position=1
01-24 11:18:08.256: D/TEST(443): > getGroupView : position=0
01-24 11:18:08.256: D/TEST(443): > getGroupView : position=1
01-24 11:18:08.256: D/TEST(443): > getChildView : position=1

在这个示例中,我只单击了其中一个组。
你需要完全重新考虑你的适配器才能工作

例如在我的代码中我有类似的东西:

/**
 * {@inheritDoc}
 */
@Override
public View getGroupView(int p_iSecteurPosition, boolean p_bIsExpanded, View p_oConvertView, ViewGroup p_oParent) {
    if (p_oConvertView==null){
        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        p_oConvertView = infalInflater.inflate(R.layout.maquette_recherche_avancee_secteur_item_layout, null);
    }

    String sLabel = (String) getGroup(p_iSecteurPosition);
    TextView oVoieLabel = (TextView) p_oConvertView.findViewById(R.id.maquette_secteur_label);
    oVoieLabel.setText(sLabel);

    return p_oConvertView;
}


/**
 * {@inheritDoc}
 */
@Override
public View getChildView(int p_iSecteurPosition, int p_iVoiePosition, boolean p_bIsLastChild, View p_oConvertView, ViewGroup p_oParent) {
    if (p_oConvertView==null){
        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        p_oConvertView = infalInflater.inflate(R.layout.maquette_recherche_avancee_voie_item_layout, null);
    }

    String sLabel = (String) getChild(p_iSecteurPosition, p_iVoiePosition);
    TextView oVoieLabel = (TextView) p_oConvertView.findViewById(R.id.maquette_voie_label);
    oVoieLabel.setText(sLabel);

    CheckBox oCheck= (CheckBox) p_oConvertView.findViewById(R.id.maquette_voie_selection);
    oCheck.setOnCheckedChangeListener(this);

    p_oConvertView.setTag(FBO_KEY, p_iSecteurPosition+SEPARATOR+p_iVoiePosition);

    return p_oConvertView;
}

这里有一个简单的教程:
http://androgue.blogspot.com/2011/08/android-expandablelistview -tutorial.html

希望我能帮忙
弗朗索瓦

In my opinion, the problem of loss of focus is the result of another problem.
Your adapter is not constructed properly. Be aware that for each item displayed on the screen, it will pass in the getChildView and getGroupView methods.
That's why the name of the group changed each time you click on it.

If i add some log in those method i can see :

01-24 11:18:02.575: D/TEST(443): > createSearchViews
01-24 11:18:02.715: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.715: D/TEST(443): > getGroupView : position=1
01-24 11:18:02.755: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.755: D/TEST(443): > getGroupView : position=1
01-24 11:18:02.845: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.845: D/TEST(443): > getGroupView : position=1
01-24 11:18:02.885: I/ActivityManager(59): Displayed activity com.test/.TestOnClickActivity: 455 ms (total 455 ms)
01-24 11:18:02.905: D/TEST(443): > getGroupView : position=0
01-24 11:18:02.905: D/TEST(443): > getGroupView : position=1
01-24 11:18:08.246: D/TEST(443): > getGroupView : position=0
01-24 11:18:08.246: D/TEST(443): > getGroupView : position=1
01-24 11:18:08.246: D/TEST(443): > getChildView : position=1
01-24 11:18:08.256: D/TEST(443): > getGroupView : position=0
01-24 11:18:08.256: D/TEST(443): > getGroupView : position=1
01-24 11:18:08.256: D/TEST(443): > getChildView : position=1

In this example I only clicked on one of the group.
you need to completely rethink your adapter for this to work

For exemple in my code i have something like :

/**
 * {@inheritDoc}
 */
@Override
public View getGroupView(int p_iSecteurPosition, boolean p_bIsExpanded, View p_oConvertView, ViewGroup p_oParent) {
    if (p_oConvertView==null){
        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        p_oConvertView = infalInflater.inflate(R.layout.maquette_recherche_avancee_secteur_item_layout, null);
    }

    String sLabel = (String) getGroup(p_iSecteurPosition);
    TextView oVoieLabel = (TextView) p_oConvertView.findViewById(R.id.maquette_secteur_label);
    oVoieLabel.setText(sLabel);

    return p_oConvertView;
}


/**
 * {@inheritDoc}
 */
@Override
public View getChildView(int p_iSecteurPosition, int p_iVoiePosition, boolean p_bIsLastChild, View p_oConvertView, ViewGroup p_oParent) {
    if (p_oConvertView==null){
        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        p_oConvertView = infalInflater.inflate(R.layout.maquette_recherche_avancee_voie_item_layout, null);
    }

    String sLabel = (String) getChild(p_iSecteurPosition, p_iVoiePosition);
    TextView oVoieLabel = (TextView) p_oConvertView.findViewById(R.id.maquette_voie_label);
    oVoieLabel.setText(sLabel);

    CheckBox oCheck= (CheckBox) p_oConvertView.findViewById(R.id.maquette_voie_selection);
    oCheck.setOnCheckedChangeListener(this);

    p_oConvertView.setTag(FBO_KEY, p_iSecteurPosition+SEPARATOR+p_iVoiePosition);

    return p_oConvertView;
}

a simple tutorial here :
http://androgue.blogspot.com/2011/08/android-expandablelistview-tutorial.html

hope i could help
François

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文