ScrollView與listView,GridView,Viewpager的沖突及解決方法!8谢臁端幼!

ScrollView是帶有滾動事件的控件,與listView和GridView以及Viewpager嵌套使用時經(jīng)常會出現(xiàn)很多問題弧满。例如listView和GridView只能在ScrollView顯示一行等婆跑。所以Google是不推薦我們?nèi)プ鯯crollView內(nèi)嵌操作的,但是有的時候庭呜,需求需要~我們不得不這么使用滑进。所以接下來我給大家講一些基礎(chǔ)的解決沖突的辦法。

1.ScrollView嵌套ListView,有2種方法解決

1.1自定義View
public class ScrollListView extends ListView {
    public ScrollListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public ScrollListView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}
1.2動態(tài)測量Listview的高度
/**
 * 動態(tài)控制listView的高度
 */
public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        return;
    }
    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
}

2.ScrollView嵌套GridView,有2種方法解決---與ListView類似

2.1自定義View
public class ScrollGridView extends GridView {
    public ScrollGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public ScrollGridView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}
2.2動態(tài)測量Gridview的高度
/**
 * 動態(tài)控制gridview的高度
 */
public static void setGridViewHeightBasedOnChildren(GridView gridView, int number) {
    //獲取listview的適配器
    ListAdapter listAdapter = gridView.getAdapter();
    int numCollumn = number;
    //item的高度
    if (listAdapter == null) {
        return;
    }
    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        if (i % numCollumn == 0) {
            View listItem = listAdapter.getView(i, null, gridView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }
    }
    ViewGroup.LayoutParams params = gridView.getLayoutParams();
    params.height = totalHeight;
    gridView.setLayoutParams(params);
}

3.ScrollView嵌套ViewPager,有2種方法解決

3.1自定義ScrollView
/** 
  * 能夠兼容ViewPager的ScrollView 
  *  
  * @Description: 解決了ViewPager在ScrollView中的滑動反彈問題 
  */  
public class ScrollViewExtend extends ScrollView {  
    // 滑動距離及坐標  
    private float xDistance, yDistance, xLast, yLast;  
  
    public ScrollViewExtend(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    }  
  
    @Override  
    public boolean onInterceptTouchEvent(MotionEvent ev) {  
        switch (ev.getAction()) {  
        case MotionEvent.ACTION_DOWN:  
            xDistance = yDistance = 0f;  
            xLast = ev.getX();  
            yLast = ev.getY();  
            break;  
        case MotionEvent.ACTION_MOVE:  
            final float curX = ev.getX();  
            final float curY = ev.getY();  
  
            xDistance += Math.abs(curX - xLast);  
            yDistance += Math.abs(curY - yLast);  
            xLast = curX;  
            yLast = curY;  
  
            if (xDistance > yDistance) {  
                return false;  
            }  
        }  
        return super.onInterceptTouchEvent(ev);  
    }  
}  
3.2自定義viewPager
public class MyViewPager extends ViewPager {
    /**
     * 觸摸時按下的點
     **/
    PointF downP = new PointF();
    /**
     * 觸摸時當前的點
     **/
    PointF curP = new PointF();
    OnSingleTouchListener onSingleTouchListener;

    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        // 每次進行onTouch事件都記錄當前的按下的坐標
        curP.x = arg0.getX();
        curP.y = arg0.getY();

        if (arg0.getAction() == MotionEvent.ACTION_DOWN) {
            // 記錄按下時候的坐標
            // 切記不可用 downP = curP 募谎,這樣在改變curP的時候扶关,downP也會改變
            downP.x = arg0.getX();
            downP.y = arg0.getY();
            // 此句代碼是為了通知他的父ViewPager現(xiàn)在進行的是本控件的操作,不要對我的操作進行干擾
            getParent().requestDisallowInterceptTouchEvent(true);
        }

        if (arg0.getAction() == MotionEvent.ACTION_MOVE) {
            // 此句代碼是為了通知他的父ViewPager現(xiàn)在進行的是本控件的操作数冬,不要對我的操作進行干擾
            getParent().requestDisallowInterceptTouchEvent(true);
        }

        if (arg0.getAction() == MotionEvent.ACTION_UP) {
            // 在up時判斷是否按下和松手的坐標為一個點
            // 如果是一個點节槐,將執(zhí)行點擊事件,這是我自己寫的點擊事件,而不是onclick
            if (downP.x == curP.x && downP.y == curP.y) {
                onSingleTouch();
                return true;
            }
        }

        return super.onTouchEvent(arg0);
    }
    /**
     * 單擊
     */
    public void onSingleTouch() {
        if (onSingleTouchListener != null) {

            onSingleTouchListener.onSingleTouch();
        }
    }

    /**
     * 創(chuàng)建點擊事件接口
     */
    public interface OnSingleTouchListener {
        public void onSingleTouch();
    }

    public void setOnSingleTouchListener(
            OnSingleTouchListener onSingleTouchListener) {
        this.onSingleTouchListener = onSingleTouchListener;
    }
}

4.若嵌套的ListView和GridView的高度超出了ScrollView铜异,那么ScrollView會自動滑到底部地来。

那么我們只需要使用一個頂部控件主動獲取焦點便能解決這個問題。解決代碼如下熙掺。

    view.setFocusable(true);  
    view.setFocusableInTouchMode(true);  
    view.requestFocus();  

備注:自定義ListView的詳細介紹 傳送門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末未斑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子币绩,更是在濱河造成了極大的恐慌蜡秽,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缆镣,死亡現(xiàn)場離奇詭異芽突,居然都是意外死亡,警方通過查閱死者的電腦和手機董瞻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門寞蚌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人钠糊,你說我怎么就攤上這事挟秤。” “怎么了抄伍?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵艘刚,是天一觀的道長。 經(jīng)常有香客問我截珍,道長攀甚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任岗喉,我火速辦了婚禮秋度,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钱床。我一直安慰自己荚斯,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布诞丽。 她就那樣靜靜地躺著鲸拥,像睡著了一般拐格。 火紅的嫁衣襯著肌膚如雪僧免。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天捏浊,我揣著相機與錄音懂衩,去河邊找鬼。 笑死,一個胖子當著我的面吹牛浊洞,可吹牛的內(nèi)容都是我干的牵敷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼法希,長吁一口氣:“原來是場噩夢啊……” “哼枷餐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起苫亦,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤毛肋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后屋剑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體润匙,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年唉匾,在試婚紗的時候發(fā)現(xiàn)自己被綠了孕讳。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡巍膘,死狀恐怖厂财,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情峡懈,我是刑警寧澤蟀苛,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站逮诲,受9級特大地震影響帜平,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梅鹦,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一裆甩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧齐唆,春花似錦嗤栓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锭弊,卻和暖如春堪澎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背味滞。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工樱蛤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钮呀,地道東北人。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓昨凡,卻偏偏與公主長得像爽醋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子便脊,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容