以 ViewPager 作为子元素的 ExpandableListView 执行 getChildView 两次

Posted

技术标签:

【中文标题】以 ViewPager 作为子元素的 ExpandableListView 执行 getChildView 两次【英文标题】:ExpandableListView with ViewPager as child-elements executes getChildView twice 【发布时间】:2019-08-31 04:38:51 【问题描述】:

我想创建一个以 viewpagers 作为子视图的可扩展列表。现在的问题是,我的代码调用了getChildView 方法两次,从而创建了我的viewpager 两次。

我还尝试使用TextView(为了方便我在此处发布的示例代码)来简化代码,但出现了同样的问题。

我最好的猜测是它与布局的高度属性有关,但无论我如何更改它,我都无法解决问题。 请帮忙。我完全迷路了。我为此代码使用了教程,从 youtube 评论部分来看,我似乎是唯一一个遇到这个问题的人。 (https://www.youtube.com/watch?v=jZxZIFnJ9jE)

(如果您需要代码的任何其他部分,请告诉我。)

delete.xml 文件如下所示

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_
    android:layout_
    android:id="@+id/sukahead">

    <TextView
        android:id="@+id/suka"
        android:layout_
        android:layout_
        android:text="suka"
        android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
        android:paddingStart="?android:attr/expandableListPreferredChildPaddingLeft"
        />

</LinearLayout>

sublist.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_
    android:layout_
    android:padding="8dp" android:background="@color/white"
    android:id="@+id/sublist">

    <TextView
        android:id="@+id/dict_entry"
        android:layout_
        android:layout_
        android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
        android:paddingStart="?android:attr/expandableListPreferredChildPaddingLeft"
        android:textSize="16sp"
        android:textColor="@color/colorAccent"
        android:text="test"
        />

</LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MainActivity"
    android:background="@color/colorPrimary">

    <EditText
        android:id="@+id/search_bar"
        android:layout_
        android:layout_
        android:hint="@string/search_hint"
        android:layout_margin="15dp"
        android:padding="5dp"
        app:layout_constraintTop_toTopOf="parent"
        android:background="@color/white"
        android:adjustViewBounds="true"
        android:maxLines="1"
        android:inputType="text"
        android:onClick="lookup_word"/>

    <LinearLayout
        android:layout_
        android:layout_
        android:layout_below="@id/search_bar"
        android:orientation="horizontal">

        <ExpandableListView
            android:id="@+id/search_result_list"
            android:layout_
            android:layout_
            android:divider="#333"
            android:dividerHeight="1dp"
            android:background="@color/white"
            android:layout_margin="15dp"/>


     </LinearLayout>

</RelativeLayout>

ExpandableListAdapter.java

package com.lunaticcoding.linguodict;

import android.content.Context;
import android.graphics.Typeface;
import android.support.v4.view.ViewPager;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

import java.util.HashMap;
import java.util.List;

public class ExpendableListAdapter extends BaseExpandableListAdapter 
    private Context context;
    private List<String> data;
    private HashMap<String, String[]> listHashMap;

    private LayoutInflater inflater;
    private String pageData[];

    public ExpendableListAdapter(Context context, List<String> list, HashMap<String, String[]> hashMap) 
        this.context = context;
        this.data = list;
        this.listHashMap = hashMap;
    


    @Override
    public int getGroupCount() 
        return data.size();
    

    @Override
    public int getChildrenCount(int groupPosition) 
        return listHashMap.get(data.get(groupPosition)).length;
    

    @Override
    public Object getGroup(int groupPosition) 
        return data.get(groupPosition);
    

    @Override
    public Object getChild(int groupPosition, int childPosition) 
        return listHashMap.get(data.get(groupPosition))[childPosition];
    

    @Override
    public long getGroupId(int groupPosition) 
        return groupPosition;
    

    @Override
    public long getChildId(int groupPosition, int childPosition) 
        return childPosition;
    

    @Override
    public boolean hasStableIds() 
        return true;
    

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) 
        String headerTitle = (String) getGroup(groupPosition);
        if(convertView == null) 
            LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.sublist, null);
        

        TextView textView = (TextView) convertView.findViewById(R.id.dict_entry);
        textView.setText(data.get(groupPosition));
        return convertView;
    

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) 
        final String childText = (String)getChild(groupPosition, childPosition);
        if(convertView == null) 
            LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.delete, null);
        
        TextView textView = (TextView) convertView.findViewById(R.id.suka);
        return convertView;
    

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) 
        return true;
    

MainActivity(仅 OnCreate)

@Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        searchBar = (EditText) findViewById(R.id.search_bar);
        searchResults = (ExpandableListView) findViewById(R.id.search_result_list);

        list_results = new ArrayList<>();
        examples_results = new HashMap<>();
        list_results.add("test1");
        list_results.add("test2");
        list_results.add("test3");

        String pageData1[] = new String[]"si", "siiii";
        String pageData2[] = new String[]"jifasfa", "sfasdfasiii";
        String pageData3[] = new String[]"jifasfa", "sfasdfasiii";
        examples_results.put(list_results.get(0), pageData1);
        examples_results.put(list_results.get(1), pageData2);
        examples_results.put(list_results.get(2), pageData3);

        searchResultsAdapter = new ExpendableListAdapter(this, list_results, examples_results);
        searchResults.setAdapter(searchResultsAdapter);

        lastExpandedPosition = -1;
        searchResults.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() 
            @Override
            public void onGroupExpand(int groupPosition) 
                if(lastExpandedPosition != -1 && (lastExpandedPosition != groupPosition))
                    searchResults.collapseGroup(lastExpandedPosition);
                
                lastExpandedPosition = groupPosition;
            
        );

    

【问题讨论】:

【参考方案1】:

在 sub_list.xml 中,layout_height 是“wrap_content”。将其更改为固定高度(某个 dp)或 match_parent 即可。

原因: wrap_content 必须计算它必须匹配的布局内容的高度,从而在之后重新加载布局 -> 多次创建列表。

【讨论】:

以上是关于以 ViewPager 作为子元素的 ExpandableListView 执行 getChildView 两次的主要内容,如果未能解决你的问题,请参考以下文章

作为 ViewPager 的一部分更新 ListFragment 中的数据

ViewPager嵌套禁止子ViewPager的滑动

ViewPager里面的ViewPager。如何水平滚动父寻呼机而不是滚动子寻呼机,但保持子寻呼机垂直滚动?

andorid自己定义ViewPager之——子ViewPager滑到边缘后直接滑动父ViewPager

Android ViewPager,ListFragments以及更新列表中的元素时更新

如何阻止 ExpandableListView 窃取子触摸事件?