I have multiple fragments which use the same container, and when a fragment is added over another, I want focus to be shifted only among the views in recently added fragment. I tried to solve it using onBackstackChangeListener() but it doesn't seem to work. As in the image I want focus only on the Pin Entry fragment but the focus is shifting to the "Enter" buttons on the fragment behind the Pin Entry Fragment as well.Please help.

- 385
- 1
- 2
- 14
-
Make topmost root of your fragments clickable in xml . – ADM Nov 27 '17 at 04:44
-
@ADM can you explain some more please ... – Nishan Khadka Nov 27 '17 at 05:01
3 Answers
I found a work around to this problem but it's not a real solution, Best answer will be marked as correct answer.
Work Around: Add Views around your layout that needs the focus to stay with in itself. For Example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:focusable="true"
android:id="@+id/left_view"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/buyOrWatch"
android:layout_width="90dp"
android:layout_height="30dp"
android:layout_margin="5dp"
android:background="@drawable/movie_buy_selector"
android:focusable="true"
android:gravity="center"
android:text="@string/buy"
android:textColor="@color/color_white" />
<TextView
android:id="@+id/preview"
android:layout_width="90dp"
android:layout_height="30dp"
android:layout_margin="5dp"
android:layout_marginTop="15dp"
android:background="@drawable/movie_buy_selector"
android:focusable="true"
android:gravity="center"
android:text="@string/preview"
android:textColor="@color/color_white" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:focusable="true"
android:id="@+id/right_view"/>
I placed the layout with the textviews in between the two focusable views with 0dp width.
Now, in your fragment class, bind those Views ,then define a focusChangeListener()
for those views. for example if leftView
binds view with id android:id="@+id/left_view"
and buyOrWatch
with TextView
having android:id="@+id/buyOrWatch"
,then,
leftView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
if(hasFocus){
buyOrWatch.requestFocus();
}
}
});
You can define similar focus change listeners for each views like above, then as long as the fragment is visible, focus stays with in the fragment. Hope this helps someone.

- 385
- 1
- 2
- 14
ViewGroup viewGroup;//assign your viewGroup
viewGroup.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
This must Work Reference from Can someone explain descendantFocusability = afterDescendants?

- 784
- 2
- 10
- 26
If you are using single container for all fragment then you need to set topmost root of your fragments clickable. Otherwise fragment behind can grab the focus for clickable items. See the fragment layout below for example.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="?selectableItemBackground"
android:gravity="center_vertical"
android:textColor="@color/white"
android:textSize="@dimen/normal_text" />
</LinearLayout>

- 20,406
- 11
- 52
- 83
-
I am afraid, this doesn't seem to work with my codes. Thanks anyway. – Nishan Khadka Nov 27 '17 at 05:26
-
Thats maybe because your enter pin fragment is wrap_content . Make if fill the parent . – ADM Nov 27 '17 at 05:28
-