簡體   English   中英

在水平ScrollView中滾動會失去焦點元素的焦點,

[英]Scrolling in Horizontal ScrollView loses focus of focused element,

滾動之前: 在此輸入圖像描述

滾動期間: 在此輸入圖像描述

我在滾動期間的期望: 在此輸入圖像描述

我的Horizo​​ntalScrollView有問題。 當我從這個視圖中選擇一個元素時,我通過調用將焦點設置為該元素:

else if (v.getParent() == candidatesScrollView.getChildAt(0))
{
    Button candidateButton = (Button) v;
    v.requestFocusFromTouch();
    v.setSelected(true);
            (...)
}

之后,當我滾動列表而不選擇其他元素時,我失去了先前所選元素的焦點。 我對這個主題做了一些研究,但沒有解決方案可以對我有用......如何在不丟失選定元素焦點的情況下滾動我的Horizo​​ntalScrollList? 任何幫助都會得到贊賞。 自從我提出這個問題以來,已經過了大約14天,但仍未找到解決方案。 請幫忙。

這是我的XML的一部分:

<HorizontalScrollView
        android:id="@+id/CandidatesHorizontalScrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/linearLayout2"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:visibility="gone" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/horizontalscrollview1_button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button"
            android:textSize="25sp" />

        (...)
        // 11 more buttons
    </LinearLayout>

</HorizontalScrollView>

UPDATE

MY CURRENT SOLUTION#1(無法正常工作):滾動后再滾動(例如向后滾動),從所選元素開始滾動。

我創建了自定義Horizo​​ntalScrollView類,在其中我重寫了onTouchEvent()方法。 我認為這不是最佳方式,因為在這種情況下,每次移動一個像素時我都要進行計算。 例如,如果我將toast.show()添加到下面的方法中,它將嘗試顯示盡可能多的我移動像素的吐司(如果我移動10個像素,它將嘗試顯示10個Toast)。 無論如何,它對我有用,並且保留了選擇和關注。

請幫我修改這段代碼,最后為這個已知問題找到一個好的答案:

@Override
public boolean onTouchEvent(MotionEvent ev)
{
    int i = 0;
    Button button = null;
    for (; i < 11; i++)
    {
        button = (Button)((LinearLayout)getChildAt(0)).getChildAt(i);
        if(button.isSelected())
            break;
    }
    super.onTouchEvent(ev);
    button.setSelected(true);
    button.requestFocusFromTouch();

    return true;
}

為了確保上面的代碼能夠工作,你需要在Horizo​​ntalScrollView中一次只有一個選定的項目,即當你按不同的按鈕時,你需要使前一個代碼設置為setSelected(false)

我目前的解決方案#2(工作不正常):

我試圖實現的解決方案#2,認為第一個不夠優雅,涉及使用手勢檢測器。 在我的自定義Horizo​​ntalListView類中,我添加了以下代碼:

構造函數:

public MyHorizontalScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    gestureDetector = new GestureDetector(context, new MyHorizontalScrollViewGestureDetector());
    this.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            gestureDetector.onTouchEvent(event);

            return true;
        }
    });
    // TODO Auto-generated constructor stub
}

MyHorizo​​ntalScrollViewGestureDetector內部類:

public class MyHorizontalScrollViewGestureDetector extends SimpleOnGestureListener
    {

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
        {
            //Here code similar like that one in solution #1
            //But the View is not scrolling, even without that code 
            super.onScroll(e1, e2, distanceX, distanceY);

            return true; 
        }
    }   

但是,列表不會滾動該解決方案。 我可以添加onScroll方法:

ScrollBy((int)positionX, (int)positionY);

這使得列表將滾動,但不是一個好的方式廣告它有時會凍結。 我想知道為什么滾動不被超級調用。 方法。

我當前的解決方案#3(工作,但它是四處走動):

因為解決方案1和解決方案2都不起作用,所以我決定不再使用焦點。 我現在所做的是,每當我點擊它時每次更改Button Button時都會更改Button Drawable。 我使用與用於聚焦按鈕(Holo)相同的Drawable。 在這種情況下,我不必擔心在Horizo​​ntalScrollView中滾動。 這個解決方案是一種循環,所以我期待任何評論,建議和編輯。

可以使用以下解決方案(我從這里采納了這個想法):

您可能想嘗試創建自己的自定義類,該類擴展HorizontalScrollView並覆蓋onScrollChanged()函數:

public class TestHorizontalScrollView extends HorizontalScrollView {

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


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        // TODO Auto-generated method stub
        Log.i("Scrolling", "X from ["+oldl+"] to ["+l+"]");
        Button button = null;
        for (; i < 11; i++)
        {
          button = (Button)((LinearLayout)getChildAt(0)).getChildAt(i);
          if(button.isSelected())
            break;
        }
        button.setSelected(true);
        button.requestFocusFromTouch();

        super.onScrollChanged(l, t, oldl, oldt);
    }

}

現在您已檢測到滾動(我們正在談論其中一個HorizontalScrollView ),您可以再次設置相應按鈕的選定狀態。 你可以試試這個解決方案,看看它是否有效。 我對解決這個問題非常感興趣,因為這個問題也非常有趣。

無論如何,我設法找到了以下文章 他們在那里說:

想象一下一個簡單的應用程序,例如ApiDemos,它顯示了一個文本項列表。 用戶可以使用軌跡球自由地瀏覽列表,他們還可以使用他們的手指滾動和推送列表。 此方案中的問題是選擇。 如果我在列表頂部選擇一個項目然后將列表向底部推送,那么選擇會發生什么? 它應該保留在項目上並滾動屏幕嗎? 在這種情況下,如果我決定用軌跡球移動選擇會發生什么? 或者更糟糕的是,如果我按下軌跡球來操作當前所選的項目,該項目不再顯示在屏幕上。 仔細考慮后,我們決定完全刪除選擇。

在觸摸模式下,沒有焦點也沒有選擇。 用戶進入觸摸模式后,網格列表中的任何選定項目都將被取消選中。 類似地,當用戶進入觸摸模式時,任何聚焦的小部件都變得不聚焦。 下圖說明了在用軌跡球選擇項目后用戶觸摸列表時會發生什么。

無論如何,那里的陳述並沒有讓我高興,我進一步發現了這個:

android:focusable="true"
android:focusableInTouchMode="true"

還設置android:clickable="true" (你也可以設置LinearLayout android:focusable="true" )。

嘗試將這些添加到按鈕和包含它們的布局。 嘗試一切。

我會盡我所能地支持你。

干杯

我記得滾動視圖有問題,我認為這與您遇到的問題類似。

我想出的解決方案是覆蓋HorizontalScrollView類中的onRequestFocusInDescendants方法。 這需要您創建從HorizontalScrollView擴展的類,如果您還沒有這樣做的話。

就我而言,我總是從方法中返回true。 這告訴調用者您已經處理了焦點更改,因此不應該嘗試進一步操作。

@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
  return true;
}

根據您的要求,您可能會發現僅在某些條件下(例如滾動正在進行時)才返回true,否則將調用轉發給超類。

除了自定義方式之外,這個問題沒有答案,因為您可能已經做過更改drawables。 原因是當你滑動時,焦點轉到Horizo​​ntalScroll,你只能專注於一個項目,聚焦多個視圖是沒有意義的。 因此要么實現一個drawable(你似乎已經完成了),要么擴展一個復選框並覆蓋它的功能,所以當它被聚焦時,它會被檢查並改變外觀。

我找到了解決問題的方法。 您可以查看更新的問題以獲取詳細信息。 基本上,我決定使用Drawable選擇器而不是使用焦點,這更容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM