FrameLayout can not get focus with key press? - android

I have a view(Let's say it is MyFramLayout) extends FrameLayout, I can not get this FrameLayout get focus when press key(I am working in TV platform).
the layout is something like this:
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.roger.MyFrameLayout
android:id="#android:id/my_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true" />
</LinearLayout>
Anyway to fix the problem?

Whenever you want your custom layout to get focus you will have to call
boolean b = yourLayout.requestFocus();
This will return a whether focus is gained or not.

Related

Not able to move view up with keyboard Android

I have gone through various answers but was unable to move my view up when keyboard is visible. I have a edittext in recyclerview on whose focus keyboard is visible.I want the tv_character_limit text to be moved up when keyboard is visible. I need the character limit text to be shown elevated with a z-index. I have set the windowSoftInputMode to adjustResize for the activity and for the fragment in view pager i have added the java code:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Thank you for help.Below is my layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rel_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#color/pink">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar_post" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_status"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp" />
<TextView
android:id="#+id/tv_character_limit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginRight="10dp"
android:layout_marginBottom="30dp"
android:text="#string/character_limit"
android:textColor="#color/tap_to_type"
android:textSize="15dp" />
</FrameLayout>
use,
android:windowSoftInputMode="adjustPan"
in the manifest file for your activity.
ex :
<activity
android:name=".View.Activity.yourActivity"
android:windowSoftInputMode="adjustPan"/>
Instead of FrameLayout, use RelativeLayout and when your EditText gets focus, just change the position of TextView by calling the RelativeLayout class method similar to layout_above.

How to remove focus from RecyclerView inside ScrollView?

I have a Scrollview which contains an ImageView and RecyclerView.
if navigation drawer opened then closed the RecyclerView auto scrolling to top, How to stop this?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollViewMain"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView_main_icons_line"
android:src="#drawable/main_line" />
...
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_activity_main_passenger_log"
android:paddingBottom="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
This problem because of recyclerView has default focus.
Solution
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
Add android:descendantFocusability="blocksDescendants" to your immediate layout of scrollView
That is because RecyclerView ALWAYS set:
setFocusableInTouchMode(true);
this is hard coded in its constructor.
so if you apply those attribute in your XML for a RecyclerView
android:focusable="false"
android:focudeableInTouchMode="false"
that would be useless, you end up with recycleView.isFocusable() == true...
so the most elegant solution is to disable foucusable for RecyclerView's Parent.
<LinearLayout
android:focusable="false"
android:focusableInTouchMode="false"
android:descendantFocusability="blocksDescendants"
...
>
<android.support.v7.widget.RecyclerView
...
/>
/>
or you can just simply setFocusable(false)
Check out clearFocus() from here Android Dev Doc.
You can set a DrawerListener to your navigation drawer and use the onDrawerStateChanged() or some of the other options from here to call clearFocus() on your RecyclerView.
Adding android:descendantFocusability="blocksDescendants" can restrict scroll to recylerview but if you have edittext inside your layout, this property can block the focus of that particular edittext too. So if you are using this property please make sure you are removing this property in your kotlin/java class once the layout loaded.
parentLayout?.descendantFocusability = FOCUS_BEFORE_DESCENDANTS
(view as ViewGroup).descendantFocusability = FOCUS_BEFORE_DESCENDANTS
Just add the following code in your linear layout, works 100% ` android:descendantFocusability="blocksDescendants"
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:descendantFocusability="blocksDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent">

Android: onTouchListener in root view (RelativeLayout) isn't working

I'm developing an Android application and I'm trying to capture OnTouch events in my whole screen. All my activities will have a header with two buttons and then a body that's going to change.
In the Activity I'm testing right now the body is a ListView, so the Activity has:
-Two Buttons at the top of the screen.
-ListView under those two buttons.
I want to capture onTouchEvents in the whole screen. I tried setting an OnTouchListener to my root RelativeLayout and set clickable=false and focusable=false to all the other views, but it's not working: the onTouch event is only triggered when I click the first button.
This is my layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
tools:context=".MainActivity" >
<include
layout="#layout/header"
android:clickable="false"
android:focusable="false" />
<ListView
android:id="#+id/lvLocations"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/header_layout"
android:clickable="false"
android:focusable="false" />
</RelativeLayout>
This is the content of #layout/header:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:weightSum="5" >
<Button
android:id="#+id/homeButton"
android:layout_width="0dip"
android:layout_height="50dp"
android:layout_marginRight="5dp"
android:layout_weight="4"
android:clickable="false"
android:focusable="false"
android:onClick="Home"
android:text="#string/home" />
<ImageButton
android:id="#+id/speechButton"
android:layout_width="0dip"
android:layout_height="50dp"
android:layout_weight="1"
android:clickable="false"
android:focusable="false"
android:onClick="ClickMediaButton"
android:src="#drawable/micro" />
</LinearLayout>
And this is the code I'm using:
findViewById(R.id.root).setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("MACT", "TOUCH!");
}
});
Like I said, my log shows TOUCH only when the homeButton is clicked. Why is that? What am I doing wrong?
Thank you!
Why not just create a custom view for your RelativeLayout that catches the touch event and then you can do whatever you want with it?
public class CustomRelativeLayout extends RelativeLayout{
CustomRelativeLayout(Context context, AttributeSet attrs){
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent ev){
//handle touch event
return true;
}
}
You would then use this relative layout in your XML by looking for that class in your projects namespace. You can of course add whatever modifiers you want but here's an example of what it looks like.
<com.example.whatever.your.project.CustomRelativeLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
Once you catch the touch you can do whatever you want with it. You can pass it to other activities, you can use it to call other methods, etc. For more on how to use custom views see this part of the android docs.
I finally managed to solve it, and to do it I redesigned my layout. Now instead of having a header and a ListView I just have a ListView in my layout:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Then I add the header layout to my ListView:
View header = (View)getLayoutInflater().inflate(R.layout.header,null);
mList.addHeaderView(header);
Now I set the onTouchListener to the ListView and voilĂ , I receive the onTouch events in the whole screen.
I know this is a restrictive solution and it can't be used with complex layouts, but I can use it in the screens I needed it.

How to prevent keyboard from opening when activity is opened in android?

In my android app, in my profile edit page, when I start the activity, the first edittext field is focused (blinking cursor), and the keyboard gets displayed.
How can I keep it being focused on startup (blinking cursor) but prevent the keyboard from showing up? If that is not possible, then just not focus the edittext on startup.
Thanks.
<EditText
android:id="#+id/textinput_firstname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="test" />
Just add this line of code in your onCreate(...) method
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
This is probably happening for EditText for most users, all you have to do is, just go to the layout file and set the layout's view groups attributes as follows:
android:focusable="true"
android:focusableInTouchMode="true"
For Example.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:background="#color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText
android:layout_width="match_parent"
android:layout_height="41dp"
/>
</LinearLayout>
Note: you have to set the attributes for the first view in the layout
no matter what it is This will set the default focus to false;

How to remove Click location after TranslateAnimation?

I have full screen RelativeLayout that contains the following:
1. FrameLayout, full screen, displaying content.
2. LinearLayout, act as a control menu, stay on top of the content #1, must be able to slide or fade in/out on request(I actually have two of these. One at the top of the screen, another at the bottom).
I have the view display correctly, the menu controller slide/fade in and out when menu button pressed. But when I slide and fade the view out, the click action remain. How do I remove this action?
I tried to call menuLayout.setVisibility(View.GONE); but the action remains.
I read some issue with TranslateAnimation but I cannot get it to work.
Can someone tell me how do I fix this? Example would be appreciated.
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99000000"
android:layout_alignParentLeft="true"
android:gravity="center_vertical"
android:id="#+id/contentFrame"
>
<ViewSwitcher
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewSwitch">
<include layout="#layout/main_car" />
</ViewSwitcher>
</FrameLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="43dp"
android:background="#drawable/um_top_bar"
android:layout_alignParentTop="true"
android:id="#+id/topMenu"
android:gravity="top"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/um_btn_home"
android:id="#+id/homeMainBtn" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/exp_menu_btn"
android:id="#+id/menuMainBtn" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF000000"
android:layout_alignParentBottom="true"
android:id="#+id/bottomMenu"
android:gravity="top"
>
<include layout="#layout/menu_bottom" />
</LinearLayout>
Ok, I got it to work at last. For anyone who may face the same problem, here's what I did.
I place empty layer and separate all menu content into separate XML file.
Here's the code:
/** Resetting bottom menu content */
private void resetBottomMenu(boolean isOpen){
bottomMenu.removeAllViews();
bottomMenu.addView(loadBottomMenu(isOpen));
// Control event handler goes here.
}
/** Load bottom menu content from XML */
private LinearLayout loadBottomMenu(boolean isOpen){
LinearLayout result = null;
if(isOpen){
result = (LinearLayout)View.inflate(this.getApplicationContext(), R.layout.menu_bottom_open, null);
}else{
result = (LinearLayout)View.inflate(this.getApplicationContext(), R.layout.menu_bottom, null);
}
return result;
}
Every time I want to slide menu in, I called resetBottomMenu then start animation on bottomMenu. If I want to close the menu, I start animation then resetBottomMenu.
It's important to remove child view in that Layout since that will remove the click action.
P.S. I'm not sure if this is the best way of doing it but I can confirm that it works. I have three menu that need to be fade/slide and they work perfectly now :)

Categories

Resources