Пользовательские представления в ExpandableListView не получают события кликов

У меня есть 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>

person Milind    schedule 24.01.2012    source источник


Ответы (1)


На мой взгляд, проблема потери фокуса является следствием другой проблемы.
Ваш адаптер неправильно сконструирован. Имейте в виду, что для каждого элемента, отображаемого на экране, он будет передан в методы 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

надеюсь, я смогу помочь Франсуа

person François BOURLIEUX    schedule 24.01.2012
comment
Название моей группы не меняется каждый раз, когда я нажимаю на нее. Разница между вашим кодом и моим, похоже, заключается в том, что я создаю представления строк один раз в onCreate, в то время как ваш код настраивает их каждый раз, когда вызываются getGroupView и getChildView. Я попробую и посмотрю, есть ли разница. - person Milind; 24.01.2012