SoFunction
Updated on 2025-04-05

Summary of solutions to conflict between Android ListView and ScrollView

Summary of solutions to conflict between Android ListView and ScrollView

As we all know, both ListView and ScrollView have scrolling capabilities. For such View controls, when ScrollView and ListView are nested with each other, it will become a problem:

Problem 1: Nesting ScrollView and ListView causes ListView to be incomplete display

Question 2: ScrollView cannot slide normally

Solution 1:

ScrollView+LinearLayout+ListView can be replaced with ScrollView+LinearLayout+LinearLayout. For development, the styles and forms of scrolling of ScrollView can be different. In addition, the content displayed by ScrollView will definitely not be too much, so this solution is reasonable and optional.

Solution 2:

Also replace: ListView has HeaderView and FooterView2 parts. Therefore, in the non-pull-down refresh and pull-up loading requirements, ListView can be used instead of ScrollView, so it is a reasonable and optional solution.

Solution three:

Actively calculate and set the height of the ListView, and the result of this ultimately leads to a similar solution-based effect. Specifically, the disadvantage is that it is overused, but it is also a reasonable solution.

public class Utility { 
    public static void setListViewHeightBasedOnChildren(ListView listView) { 
      ListAdapter listAdapter = ();  
      if (listAdapter == null) { 
        return; 
      } 
 
      int totalHeight = 0; 
      for (int i = 0; i < (); i++) { 
        View listItem = (i, null, listView); 
        (0, 0); 
        totalHeight += (); 
      } 
 
       params = (); 
       = totalHeight + (() * (() - 1)); 
      (params); 
    } 
  } 

Solution 4:

Rewrite ScrollView to process from the event direction, the disadvantage is that it is not flexible enough,

public class ListScrollView extends ScrollView { 
 private List list = new ArrayList(); 
 private int scrollPaddingTop; // Top inner margin of scrollview private int scrollPaddingLeft;// The left inner margin of scrollview private int[] scrollLoaction = new int[2]; // The position of scrollview in the window private final static int UPGLIDE = 0; 
 private final static int DOWNGLIDE = 1; 
 private int glideState; 
 public ListScrollView(Context context, AttributeSet attrs) { 
 super(context, attrs); 
 } 
 private int downY = 0; 
 private int moveY = 0; 
  
 @Override 
 public boolean dispatchTouchEvent(MotionEvent ev) { 
 switch (()) { 
 case MotionEvent.ACTION_DOWN: 
  downY = (int) (); 
  //("actiondown" + ()); 
  break; 
 case MotionEvent.ACTION_MOVE: 
  moveY= (int) (); 
  //("move" + moveY + "down" + downY); 
  if((moveY - downY) &gt;= 0) { 
  //("'''''''''DOWNGLIDE'''''''''''"); 
  glideState = DOWNGLIDE; 
  } else { 
  //("'''''''''UPGLIDE'''''''''''"); 
  glideState = UPGLIDE; 
  } 
  break; 
 case MotionEvent.ACTION_UP: 
 default: 
  break; 
 } 
 return (ev); 
 } 
 @Override 
 public boolean onInterceptTouchEvent(MotionEvent ev) { 
 // The xy of the event is to 00 points in the upper left corner of the scrollview instead of 00 points in the window int x = (int) () + scrollLoaction[0]; 
 int y = (int) () + scrollLoaction[1]; 
 for (int i = 0; i &lt; (); i++) { 
  ListView listView = (i); 
  int[] location = new int[2]; 
  (location); 
  int width = (); 
  int height = (); 
  // You can slide within the listview position  if (x &gt;= location[0] + scrollPaddingLeft 
   &amp;&amp; x &lt;= location[0] + scrollPaddingLeft + width 
   &amp;&amp; y &gt;= location[1] + scrollPaddingTop 
   &amp;&amp; y &lt;= location[1] + scrollPaddingTop + height) { 
  //(glideState); 
  if(( (() == (()-1)) &amp;&amp; (glideState == UPGLIDE) ) ) { 
   //("up"); 
   break; 
  } 
  if(( (() == 0) &amp;&amp; (glideState == DOWNGLIDE))) { 
   //("down"); 
   break; 
  } 
  return false; //Let the child control handle it directly  } 
 } 
 return (ev); 
 } 
 @Override 
 public boolean onTouchEvent(MotionEvent ev) { 
 return (ev); 
 } 
  
  
 private void findAllListView(View view) { 
 if (view instanceof ViewGroup) { 
  int count = ((ViewGroup) view).getChildCount(); 
  for (int i = 0; i &lt; count; i++) { 
  if (!(view instanceof ListView)) { 
   findAllListView(((ViewGroup) view).getChildAt(i)); 
  } 
  } 
  if (view instanceof ListView) { 
  ((ListView) view); 
  } 
 } 
 } 
 @Override 
 protected void onDraw(Canvas canvas) { 
 (canvas); 
 scrollPaddingTop = getTop(); 
 scrollPaddingLeft = getLeft(); 
 getLocationInWindow(scrollLoaction); 
 } 
 @Override 
 protected void onLayout(boolean changed, int l, int t, int r, int b) { 
 (changed, l, t, r, b); 
 if (() != 1) { 
  try { 
  throw new ScrollException(); 
  } catch (ScrollException e) { 
  (); 
  } 
 } 
 (); 
 findAllListView((0)); 
 } 
} 

Thank you for reading, I hope it can help you. Thank you for your support for this site!