【问题标题】:Android ExpandableListView: how to detect when the scroll hits the bottom/end of listAndroid ExpandableListView:如何检测滚动何时到达列表的底部/末尾
【发布时间】:2019-12-06 13:47:10
【问题描述】:

我正在我的应用程序上实现ExpandableListView,并尝试检测滚动何时到达ExpandableListView 的底部。我试过使用onScrollListeneronScrollChangedListener

对于onScrollListener,它被调用的次数太多,无法接受。

但是对于onScrollChangedListener,这似乎是我想要的。问题是ExpandableListView 没有 1 个子级别而是 2 个子级别,我无法找到一种方法来识别最后一个可见元素。

是否有人已经在ExpandableListView 上实现了这种行为?

【问题讨论】:

    标签: android kotlin expandablelistview


    【解决方案1】:

    试试这个解决方案 Detect when RecyclerView reaches the bottom most position while scrolling - 检查 Kaustubh Bhagwat 的答案

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
    
            if (!recyclerView.canScrollVertically(1)) {
                Toast.makeText(YourActivity.this, "Last", Toast.LENGTH_LONG).show();
    
            }
        }
    });
    

    【讨论】:

    • 最后,onScrollChangedListener 不是我需要的。我需要一个仅在用户投掷时触发的侦听器,认为onScrollChangedListener 适合此,考虑到它是我能为ExpandableListView 找到的最精确的。你知道是否可以将它放在ExpandableListView 上?
    • 我正在尝试理解您的问题...您需要监听器到达可扩展列表视图最后一条记录的最后一条记录吗?
    • 我想做的是:当用户位于列表末尾时,在ExpandableListView 上加载更多数据。第一个问题是ExpandableListView 有组和孩子。而且我无法确定最后一个元素是封闭组还是扩展组的子元素。第二个是onScrollListeneronScrollChangeListener被调用太频繁,导致加载更多数据时调用太多。
    • 以编程方式将一个孩子添加到最后一组的末尾。如果孩子可见,则加载更多数据...可能对您有用。如果您喜欢建议,请告诉我,或者如果我不明白您的问题,您可以标记我的答案 -1
    • @A.Danibo 你试过我上面贴的解决方案了吗?
    【解决方案2】:

    您可以通过获取最后一组展开时的位置来完成

    expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                if(groupPosition == expandableListView.getExpandableListAdapter().getGroupCount()){
                // your code goes here
                }
                return false;
            }
        });
    

    【讨论】:

      【解决方案3】:

      试试下面的示例:-

      activity_main.xml:

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout 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_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical"
      tools:context=".MainActivity">
      
      <ExpandableListView
          android:id="@+id/elvMain"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      </ExpandableListView>
      
      </LinearLayout>
      

      MainActivity.java:

      public class MainActivity extends AppCompatActivity {
      ArrayList<String> mainGroupList;
      HashMap<String, ArrayList<String>> mainChildList;
      CustomAdapter mainAdapter;
      ExpandableListView elvMain;
      int newDataSet = 0;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
      
          elvMain = findViewById(R.id.elvMain);
          mainGroupList = new ArrayList<>();
          mainChildList = new HashMap<>();
          for(int i = 0; i < 20; i++){
              ArrayList<String> tmpList = new ArrayList<>();
              for(int j = 0; j< 17; j++){
                  tmpList.add("Child " + j);
              }
              mainChildList.put("Group " + i, tmpList);
              mainGroupList.add("Group " + i);
          }
          mainAdapter = new CustomAdapter(this, mainGroupList, mainChildList);
          elvMain.setAdapter(mainAdapter);
      
          elvMain.setOnScrollListener(new AbsListView.OnScrollListener() {
              @Override
              public void onScrollStateChanged(AbsListView absListView, int i) {}
              @Override
              public void onScroll(AbsListView absListView, int i, int i1, int i2) {
                  if(i2 == i + i1){
                      View lastView = absListView.getChildAt(i1 - 1);
                      if(lastView.getBottom() == absListView.getBottom()){
                          try{
                              String viewTag = lastView.getTag().toString();
                              if(viewTag.equals("Group")){
                                  Toast.makeText(getApplicationContext(),
                                          "No more data, unless expanded the last group!!",
                                          Toast.LENGTH_SHORT).show();
                                  //elvMain.expandGroup(mainAdapter.getGroupCount() - 1);
                              }
                          }catch(Exception e){
                              addNewData();
                          }
                      }
                  }
              }
          });
      }
      
      private void addNewData(){
          newDataSet++;
          for(int i = 0; i < 5; i++){
              ArrayList<String> tmpList = new ArrayList<>();
              for(int j = 0; j< 7; j++){
                  tmpList.add("Child " + j);
              }
              mainChildList.put("Added " + newDataSet + ",Group " + i, tmpList);
              mainGroupList.add("Added " + newDataSet + ",Group " + i);
          }
          mainAdapter.notifyDataSetChanged();
      }
      }
      

      CustomAdapter.java:

      public class CustomAdapter extends BaseExpandableListAdapter {
      ArrayList<String> groupList;
      HashMap<String, ArrayList<String>> childList;
      LayoutInflater inflater;
      
      public CustomAdapter(Context context, ArrayList<String> groupList, HashMap<String, ArrayList<String>> childList) {
          this.inflater = LayoutInflater.from(context);
          this.groupList = groupList;
          this.childList = childList;
      }
      
      @Override
      public int getGroupCount() {
          return groupList.size();
      }
      
      @Override
      public int getChildrenCount(int i) {
          return childList.get(groupList.get(i)).size();
      }
      
      @Override
      public String getGroup(int i) {
          return groupList.get(i);
      }
      
      @Override
      public String getChild(int i, int i1) {
          return childList.get(groupList.get(i)).get(i1);
      }
      
      @Override
      public long getGroupId(int i) {
          return i;
      }
      
      @Override
      public long getChildId(int i, int i1) {
          return 0;
      }
      
      @Override
      public boolean hasStableIds() {
          return false;
      }
      
      @Override
      public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
          if(view == null) view = inflater.inflate(android.R.layout.simple_list_item_1, null);
          TextView textView = view.findViewById(android.R.id.text1);
          textView.setText(getGroup(i));
          view.setTag("Group");
          return view;
      }
      
      @Override
      public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
          if(view == null) view = inflater.inflate(android.R.layout.simple_list_item_1, null);
          TextView textView = view.findViewById(android.R.id.text1);
          textView.setText(getChild(i, i1));
          return view;
      }
      
      @Override
      public boolean isChildSelectable(int i, int i1) {
          return false;
      }
      }
      

      在这个示例中,我使用 setTag() 来识别视图是“组”。如果您对组视图和子视图使用不同的布局,那么您可以使用 findViewById() 来查找组视图内的视图,因此您的适配器不会发生任何变化。

      另外,在try-catch中,你可以注释掉Toast(),并启用代码elvMain.expandGroup(mainAdapter.getGroupCount() - 1);,它会在列表滚动到底部时自动展开最后一个组,所以ExpandableListView 变得无穷无尽。

      希望有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-30
        • 1970-01-01
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        • 2019-06-16
        相关资源
        最近更新 更多