[英]Scrolling in Horizontal ScrollView loses focus of focused element,
滾動之前:
滾動期間:
我在滾動期間的期望:
我的HorizontalScrollView有問題。 當我從這個視圖中選擇一個元素時,我通過調用將焦點設置為該元素:
else if (v.getParent() == candidatesScrollView.getChildAt(0))
{
Button candidateButton = (Button) v;
v.requestFocusFromTouch();
v.setSelected(true);
(...)
}
之后,當我滾動列表而不選擇其他元素時,我失去了先前所選元素的焦點。 我對這個主題做了一些研究,但沒有解決方案可以對我有用......如何在不丟失選定元素焦點的情況下滾動我的HorizontalScrollList? 任何幫助都會得到贊賞。 自從我提出這個問題以來,已經過了大約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(無法正常工作):滾動后再滾動(例如向后滾動),從所選元素開始滾動。
我創建了自定義HorizontalScrollView類,在其中我重寫了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;
}
為了確保上面的代碼能夠工作,你需要在HorizontalScrollView中一次只有一個選定的項目,即當你按不同的按鈕時,你需要使前一個代碼設置為setSelected(false)
我目前的解決方案#2(工作不正常):
我試圖實現的解決方案#2,認為第一個不夠優雅,涉及使用手勢檢測器。 在我的自定義HorizontalListView類中,我添加了以下代碼:
構造函數:
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
}
MyHorizontalScrollViewGestureDetector內部類:
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。 在這種情況下,我不必擔心在HorizontalScrollView中滾動。 這個解決方案是一種循環,所以我期待任何評論,建議和編輯。
可以使用以下解決方案(我從這里采納了這個想法):
您可能想嘗試創建自己的自定義類,該類擴展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。 原因是當你滑動時,焦點轉到HorizontalScroll,你只能專注於一個項目,聚焦多個視圖是沒有意義的。 因此要么實現一個drawable(你似乎已經完成了),要么擴展一個復選框並覆蓋它的功能,所以當它被聚焦時,它會被檢查並改變外觀。
我找到了解決問題的方法。 您可以查看更新的問題以獲取詳細信息。 基本上,我決定使用Drawable選擇器而不是使用焦點,這更容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.