I want to listen to a ScrollView to see if it is scrolling. I used OnTouchListener, it works well. But when I want to add compatibility to trackball using OnKeyListener or overriding the OnKeydown method, it can't work. Seems like the child buttons taking the focus causes the problem.
Any solution or workaround to resolve this problem? Any help is appreciated.
Here are some demo codes to reproduce my problem:
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ScrollView scrollView = (ScrollView) findViewById(R.id.scroll_view);
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout);
LinearLayout.LayoutParams wrapParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
for (int i = 0; i < 100; i++) {
MyItem item = (MyItem) LayoutInflater.from(this).inflate(R.layout.item, null);
item.setParent(scrollView);
item.setBackgroundColor(Color.WHITE);
item.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
mainLayout.addView(item, wrapParams);
}
scrollView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// can go into here
}
});
scrollView.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
// never go in, unless no child button get focus
}
return false;
}
});
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<com.fannyxie.MyScroller
android:id="@+id/scroll_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:descendantFocusability="beforeDescendants"
android:clickable="true"
android:focusable="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout android:id="@+id/main_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</com.fannyxie.MyScroller>
</LinearLayout>
item.xml:
<?xml version="1.0" encoding="utf-8"?>
<com.fannyxie.MyItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TITLE"/>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/myButton" android:text="Button"></Button>
</com.fannyxie.MyItem>
MyScroller.java
public class MyScroller extends ScrollView {
public MyScroller(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//not go into here...
Log.i("MyScroller", "onKeyDown");
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
//not go into here...
Log.i("MyScroller", "onTrackballEvent");
return super.onTrackballEvent(event);
}
@Override
protected boolean onRequestFocusInDescendants(int direction,
Rect previouslyFocusedRect) {
//some times go into here, when no button get the focus when entering first time
Log.i("MyScroller", "request focus in descendants");
return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
}
}
MyItem.java
public class MyItem extends LinearLayout {
private Button myButton;
public MyItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean onRequestFocusInDescendants(int direction,
Rect previouslyFocusedRect) {
// never go into here
Log.i("MyItem", "request focus in descendants");
return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
}
}
Thanks @Jeffrey. But I found a better way to do it. Just override the dispatchkeyevent method in ScrollView and handle trackball/keyboard events there. It works well.
public class MyScroller extends ScrollView {
public MyScroller(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if ((KeyEvent.KEYCODE_DPAD_UP == event.getKeyCode() || KeyEvent.KEYCODE_DPAD_DOWN == event.getKeyCode())) {
//handle key events here
}
return super.dispatchKeyEvent(event);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With