ScrollView嵌套ListView引起的沖突

ScrollView與ListView合用(正確計(jì)算Listview的高度)的問(wèn)題解決
首先,ListView不能直接用,要自定義一個(gè),然后重寫(xiě)onMeasure()方法:

@Override  
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,  
            MeasureSpec.AT_MOST);  
    super.onMeasure(widthMeasureSpec, expandSpec);  
} 

第二步:寫(xiě)個(gè)計(jì)算listView每個(gè)Item的方法:

public void setListViewHeightBasedOnChildren(ListView listView) {
  // 獲取ListView對(duì)應(yīng)的Adapter
  ListAdapter listAdapter = listView.getAdapter();
  if (listAdapter == null) {
   return;
  }
  int totalHeight = 0;
  for (int i = 0; i < listAdapter.getCount(); i++) { // listAdapter.getCount()返回?cái)?shù)據(jù)項(xiàng)的數(shù)目
   View listItem = listAdapter.getView(i, null, listView);
   listItem.measure(0, 0); // 計(jì)算子項(xiàng)View 的寬高
   totalHeight += listItem.getMeasuredHeight(); // 統(tǒng)計(jì)所有子項(xiàng)的總高度
  }
  ViewGroup.LayoutParams params = listView.getLayoutParams();
  params.height = totalHeight
    + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
  // listView.getDividerHeight()獲取子項(xiàng)間分隔符占用的高度
  // params.height最后得到整個(gè)ListView完整顯示需要的高度
  listView.setLayoutParams(params);
 }

第三步:listview添加適配器后設(shè)置高度即可:

listView.setAdapter(adapter);  
new ListViewUtil().setListViewHeightBasedOnChildren(listView);  

要注意的是,子ListView的每個(gè)Item必須是LinearLayout,不能是其他的,因?yàn)槠渌腖ayout(如RelativeLayout)沒(méi)有重寫(xiě)onMeasure(),所以會(huì)在onMeasure()時(shí)拋出異常。

需要手動(dòng)把ScrollView滾動(dòng)至最頂端,因?yàn)槭褂眠@個(gè)方法的話,默認(rèn)在ScrollView頂端的項(xiàng)是ListView,具體原因不了解,求大神解答…可以在Activity中設(shè)置:

mSlTimeLine.smoothScrollTo(0,0);
mScrollView.scrollTo(x, y)首次初始化時(shí)無(wú)效果

listview點(diǎn)擊事件無(wú)法響應(yīng)時(shí)要自定義listview
自定義的listview一定要構(gòu)造兩個(gè)參數(shù)的構(gòu)造方法,一個(gè)參數(shù)的運(yùn)行異常。并重寫(xiě)onInterceptTouchEvent方法

   public SpinListView(Context context, AttributeSet attrs) {  
       super(context, attrs);  
       // TODO Auto-generated constructor stub  
   }  

int flag = 0;
    float StartX;
    float StartY;
    float ScollX;
    float ScollY;
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
//總是調(diào)用listview的touch事件處理
        onTouchEvent(ev);
        if(ev.getAction()==MotionEvent.ACTION_DOWN){
            StartX = ev.getX();
            StartY = ev.getY();
            return false;
        }
        if(ev.getAction()==MotionEvent.ACTION_MOVE){
            ScollX = ev.getX()-StartX;
            ScollY = ev.getY()-StartY;
//判斷是橫滑還是豎滑,豎滑的話攔截move事件和up事件(不攔截會(huì)由于listview和scrollview同時(shí)執(zhí)行滑動(dòng)卡頓)
            if(Math.abs(ScollX)<Math.abs(ScollY)){
                flag = 1;
                return true;
            }
            return false;
        }
        if(ev.getAction()==MotionEvent.ACTION_UP){
            if(flag==1){
                return true;
            }
            return false;
        }
        return super.onInterceptTouchEvent(ev);
    }

scrollview隱藏滾動(dòng)條

ScrollView sView = (ScrollView)findViewById(R.id.sView);

sView.setVerticalScrollBarEnabled(false); //禁用垂直滾動(dòng) sView.setHorizontalScrollBarEnabled(false); //禁用水平滾動(dòng)

一種是在XML的ScrollView布局中加入屬性Android:scrollbars="none"

解決ScrollView中有l(wèi)istView,造成不屏幕不停留在頂端的問(wèn)題

這個(gè)問(wèn)題造成的原因 其實(shí)是加載ListView之后  ScrollView 的焦點(diǎn)異常   然后看上去被頂上去的

其實(shí)有兩個(gè)方法可以解決 這個(gè)問(wèn)題 
一個(gè)是
scrollView.smoothScrollTo(0,20);
顧名思義  這個(gè)是讓屏幕滾動(dòng)到頂端的意思。  可有的時(shí)候 必須用TabHost  等頁(yè)面切換Fragment的時(shí)候 
這個(gè)方法找不到合適的地方加    寫(xiě)在生命周期里  也可能不調(diào)用  所有就有了第二種方法
在XML文件里   讓listView失去焦點(diǎn)   
只需要在父容器中加入這兩條屬性
android:focusable="true"
android:focusableInTouchMode="true"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容