Today i found some posts about how to celar the focus of an EditText.
It was recommed to do this:
Set focusable and focuableInTouchMode to true for the parent layout:
<LinearLayout
android:id="#+id/my_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000000"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true" >
<EditText
android:id="#+id/calc_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal" />
And to use this in the DialogFragment:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.textEditCalcInput = (EditText) view.findViewById(R.id.calc_input);
this.textEditCalcInput.clearFocus();
view.findViewById(R.id.my_layout).requestFocus();
}
But unfortunately this does not work. The textfield always has the focus when the ui appears.
So how to remove the focus?
Here i want the AlertDialog to be shown and the Keyboard to be hidden.
Instead of
android:focusable="true"
android:focusableInTouchMode="true"
in LinearLayout use:
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
Note that you can also use
android:windowSoftInputMode="stateHidden"
in AndroidManifest.XML.
Another solution is adding
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
to onCreate of the Activity in order to hide keyboard whenever the activity starts.
Try this in manifest:
<activity
android:name=".YourActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="stateHidden" >
</activity>
and if doesn't work try this in your Activity:
#Override
public void onConfigurationChanged(Configuration mConfig) {
super.onConfigurationChanged(mConfig);
int orientation = getResources().getConfiguration().orientation;
switch(orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//hide keyboard
break;
case Configuration.ORIENTATION_PORTRAIT:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//do whatever you want
break;
default:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
//do whatever you want
break;
}
}
Related
I have an activity with some edittexts and some checkboxes, etc.
I have validators set on text entries that get executed when a text entry loses focus. But the problem is when the user clicks/touches a checkbox, edittext doesn't lose focus and therefore the validator is not run.
What is the best way for causing unfocus of text entries when the user touches another input field? I know I can e.g. set a handler on every checkbox to force unfocusing of text fields happen, but I think there is probably a more concise/general method for this purpose; Setting a handler on every checkbox seems too cumbersome and error prone.
thank u.
You can try this way(it only is an example).
your_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sv_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="EditText 1" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="EditText 2" />
..............other views................
</LinearLayout>
</ScrollView>
Using android:focusableInTouchMode="true" in the LinearLayout to make the EditText is focused when touching on it( or when starting this activity there is not auto focus to any EditText also).
In your activity:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
ScrollView svContent = findViewById(R.id.sv_content);
svContent.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
int action = motionEvent.getAction();
if(action == MotionEvent.ACTION_MOVE || action == MotionEvent.ACTION_UP) {
View focusView = getCurrentFocus();
if (focusView != null) {
// The code for unfocus here
return true;
}
}
return false;
}
});
}
I'm trying to adjust the layout when the soft keyboard appears after an edit text gets focus. Right now if I have many edit text and the keyboard appears, the last edit text are hidden and I can't scroll up.
This is how my layout is builded up:
Template:
<LinearLayout>
<LinearLayout>
// header 1
</LinearLayout>
<LinearLayout>
// header 1
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:orientation="vertical">
// where I inflate view_1
</LinearLayout>
<LinearLayout>
// footer
</LinearLayout>
</LinearLayout>
View (view_1):
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true">
<LinearLayout>
// ...
</LinearLayout>
<LinearLayout>
// ...
</LinearLayout>
<LinearLayout>
<TextView/>
<EditText/>
<TextView/>
<EditText/>
<TextView/>
<EditText/>
<TextView/>
<EditText/>
</LinearLayout>
</LinearLayout>
</ScrollView>
I already try all kinds of combinations of android:windowSoftInputMode (on manifest.xml and programmatically). I tried to set android:isScrollContainer="false" on the scroll view, but nothing.
I also tried this answer, putting an GlobalLayoutListener in my scroll view, but the onGlobalLayout is not called when the keyboard appears. And the isKeyboardShown is always false.
The best solution I found is to add adjustpan property in the activity<> tag in the manifest.xml file .
<activity
android:name="MyActivity"
android:windowSoftInputMode="adjustPan"/>
I ended up doing it my way.
I created a class that implements OnFocusChangeListener to handle all my EditText:
public class EditTextFocusChangeListener implements OnFocusChangeListener {
private ScrollView scrollView;
public EditTextFocusChangeListener(ScrollView scrollView) {
this.scrollView = scrollView;
}
#Override
public void onFocusChange(View view, boolean hasFocus) {
if(hasFocus) {
int left = view.getLeft();
int top = view.getTop();
int bottom = view.getBottom();
int keyboardHeight = scrollView.getHeight() / 3;
// if the bottom of edit text is greater than scroll view height divide by 3,
// it means that the keyboard is visible
if (bottom > keyboardHeight) {
// increase scroll view with padding
scrollView.setPadding(0, 0, 0, keyboardHeight);
// scroll to the edit text position
scrollView.scrollTo(left, top);
}
}
}
}
Then in the activity, I setted the listener for each edit text:
EditTextFocusChangeListener listener = new EditTextFocusChangeListener(mainScrollView);
editText1 = (EditText) findViewById(R.id.editText1);
editText1.setOnFocusChangeListener(listener);
editText2 = (EditText) findViewById(R.id.editText2);
editText2.setOnFocusChangeListener(listener);
...
editTextN = (EditText) findViewById(R.id.editTextN);
editTextN.setOnFocusChangeListener(listener);
And for the last edit text, I setted an EditorAction listerner to handle the 'Done' button on soft keyboard - to hide the keyboard and put the scroll view back to its original position:
editTextN.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
int result = actionId & EditorInfo.IME_MASK_ACTION;
switch(result) {
// user taped on keyboard DONE button
case EditorInfo.IME_ACTION_DONE:
// put the scroll view back to its original position
mainScrollView.setPadding(0, 0, 0, 0);
// hide keyboard
((InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
// remove focus from any edit text
LinearLayout scrollViewLL = (LinearLayout) mainScrollView.getChildAt(0);
scrollViewLL.requestFocus();
break;
}
return false;
}
});
And finally, a way to handle when the user touches outside an edit text to hide the keyboard and put the scroll view back to its original position (found this on web and changed a little to fit my needs):
public void setupUI(View view) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// put the scroll view back to its original position
if (v instanceof ScrollView) {
v.setPadding(0, 0, 0, 0);
LinearLayout scrollViewLL = (LinearLayout) ((ScrollView) v).getChildAt(0);
scrollViewLL.requestFocus();
}
hideKeyboard();
return false;
}
});
}
// If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
This is a late answer, but it may be helpful for anyone that is still looking for an alternative solution. I created a custom ViewTreeObserver.OnGlobalLayoutListener that may fit your use case if you're looking for a way to control the position of the View that you want to ensure is visible when the soft keyboard is shown. Here is a gist to that solution.
The OnGlobalLayoutListener animates changes to the view's translationY property by smoothly moving the view just above the soft keyboard bounds when the keyboard is shown and back to the view's starting position when the the keyboard is dismissed. Let me know if you have any questions on usage.
Put all of your top code in ScrollView, not just view_1. This allows you to move all the parent layout on click by any child EditText.
EDIT: view_1 in this case MUST NOT contains ScrollView!
If you create the Activity using Android Studio Basic Activity wizard (with CoordinatorLayout and theme="#style/AppTheme.NoActionBar"), the default behavior is adjustPan, where the top portion of the activity is push offscreen and the EditText is shown above the Keyboard. You can also change it to adjustResize where the top portion of the activity is maintained.
Edit AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<application ...>
<activity
android:name=".TestInputActivity"
android:label="#string/title_activity_test_input"
android:windowSoftInputMode="adjustResize"
android:theme="#style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>
Keep in mind though the effect and behavior might differ slightly if you are using Scrolling Activity, such as NestedScrollView.
https://code.luasoftware.com/tutorials/android/move-layout-when-keyboard-shown/
android:weightSum="1"
add this
The below code is working for me. Just try this example:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/RelativeAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.scrollview.MainActivity">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<EditText
android:id="#+id/editTextUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:ems="10"
android:inputType="textPersonName"
android:hint="Name" />
<EditText
android:id="#+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/editTextUserName"
android:layout_alignLeft="#+id/editTextUserName"
android:layout_alignRight="#+id/editTextUserName"
android:layout_alignStart="#+id/editTextUserName"
android:layout_below="#+id/editTextUserName"
android:layout_marginTop="20dp"
android:ems="10"
android:inputType="textPersonName"
android:hint="Address" />
<Button
android:id="#+id/buttonLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/address"
android:layout_centerHorizontal="true"
android:layout_marginTop="47dp"
android:text="Button" />
</RelativeLayout>
</ScrollView>
</RelativeLayout>
In manifest.xml add these line:
android:theme="#style/AppTheme"
android:windowSoftInputMode="stateHidden|adjustPan"
Declare AppTheme in style.xml as per your theme requirement. Then if you do not need keyboard comes up while page loads, you can add below line in activity:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Happy Coding :-)
In my Activity I have a View that "depends" from screen orientation. If it's in landscape mode, i use a layout under layout-large-hand, but if it's in portrait mode, I use the layouts under the layouts folder.
The Activity shows also a Map with some markers and informations.
In my AndroidManifest i have
android:configChanges="orientation|screenSize"
But the activity shows only the layout on portrait mode.
How can I fix this?
EDIT 3/12:
I have a layout like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
<include
android:id="#+id/my_view"
layout="#layout/my_view"
android:visibility="gone" />
</RelativeLayout>
and i want that my_view changes the layout, but map remains with all markers, zoom level, position, ecc ecc...
my_view is visible when i click on a Button created dinamically in the activity.
EDIT 2:
Like SweetWisher ツ says, i was trying to setup a custom behaviour for the views. But when i rotate the device, the map disappear. This is part of my code in the activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initUI();
}
private void initUI() {
setContentView(R.layout.my_layout);
if (mp == null) {
mp = MapFragment.newInstance();
}
getFragmentManager().beginTransaction().replace(R.id.placeholder, mp).commit();
initUIStuff()
}
private void initUIStuff(){
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
initUI();
}
#Override
protected void onStart() {
super.onStart();
initGMap();
}
#Override
protected void onResume() {
super.onResume();
initGMap();
}
private void initGMap() {
if (mp != null {
//Initialize Map
}
}
If you use android:configChanges="orientation" in your Manifest you're preventing Android from doing default reset of view hierarchy on screen orientation change. You have to manually change your views in onConfigurationChanged method and by that I mean inflate your desired layout and replace your old layout with it. If you want to take advantage of Android automatic view hierarchy reset don't use android:configChanges="orientation".
Edit:
Use following code to add map fragment through XML:
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
You also don't need now 'onConfigurationChange' method so delete it.
After a specific button is clicked, a popup window appears on the screen. There is a edittext object on the popup, but I couldn't write int it, because keyboard doesn't appears. Secondly, the other buttons on parent view of popup are still clickable. How can I fix these? My code:
edit_text_popup.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dip"
android:background="#color/conn_text" >
<EditText
android:id="#+id/editTextInPopup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hello_world"
android:padding="5dip"
android:background="#color/blue3">
</EditText>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="10dip">
<Button
android:id="#+id/popupcommitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ok"/>
<Button
android:id="#+id/popupcancelbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/cancel"
android:layout_alignParentRight="true" />
</RelativeLayout>
</LinearLayout>
where popup is called:
public class GroupConnections extends Activity implements OnClickListener {
Category thiscat;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_connections);
View addMoreConnButton =findViewById(R.id.attachMorePeopleButton);
View editPropButton = findViewById(R.id.editCategoryPropertiesButton);
addMoreConnButton.setOnClickListener(this);
editPropButton.setOnClickListener(this);
//get selected category
int catId = getIntent().getExtras().getInt("categoryid");
thiscat = (Category)SocialRssModel.Instance().holders.get(catId);
//set text views
TableRow tabler = (TableRow)findViewById(R.id.tableRow1);
TextView cateNameTextView = (TextView)tabler.findViewById(R.id.numOfContentsTextView2);
cateNameTextView.setText(thiscat.getName());
tabler = (TableRow)findViewById(R.id.tableRow2);
CheckBox enable = (CheckBox)tabler.findViewById(R.id.notificationCheckBox);
enable.setChecked(thiscat.isSelected());
}
/**
* Button listeners are specified
*/
public void onClick(View v) {
switch (v.getId()) {
case R.id.attachMorePeopleButton:
Intent i = new Intent(this, AddMoreConnections.class);
startActivity(i);
break;
case R.id.editCategoryPropertiesButton:
LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.edit_text_popup, null);
final PopupWindow editpopup = new PopupWindow(popupView,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
//specify cancel button
View cancelbutton = popupView.findViewById(R.id.popupcancelbutton);
cancelbutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
editpopup.dismiss();
}
});
//specify edittext
editpopup.setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
editpopup.showAsDropDown(findViewById(R.id.editCategoryPropertiesButton), 0, -30);
break;
// More buttons go here (if any) ...
}
}
}
Activity tag in AndroidManifest to show softInputMode is not hidden:
<activity
android:name=".GroupConnections"
android:label="#string/app_name" >
</activity>
I found the solution on the following link : EditText On A Popup Window
Adding following command editpopup.setFocusable(true); solves both problems.
I have similar problem. Try to add this line in your activity tag in manifest.xml :
android:windowSoftInputMode="stateVisible"
Change your Popup Dialog to an activity, use this code in your manifest.xml, it's show your activity as Dialog, You can start it as a usual activity but it's showing such a dialog, this will be easier for show a custom dialog:
<activity
android:name=".view.MyDialog"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateVisible"
android:theme="#android:style/Theme.Dialog" >
</activity>
I have two layouts xml and can't get the second layout to work correctly.
A EditText placed on the second layout doesn't work as expected. It doesn't accept characters.
What am i missing here?
Should i use startActivity() instead?
Main.java
public class Main extends Activity implements View.OnClickListener {
EditText box1, box2;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
showXml1();
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
String box11 = box1.getText().toString();
Toast.makeText(this, box11,Toast.LENGTH_SHORT).show();
showXml2();
break;
case R.id.button2:
String box22 = box2.getText().toString();
Toast.makeText(this, box22,Toast.LENGTH_SHORT).show();
showXml1();
break;
}
}
public void showXml2() {
setContentView(R.layout.main2);
box2 = (EditText) findViewById(R.id.editText2);
}
public void showXml1() {
setContentView(R.layout.main);
box1 = (EditText) findViewById(R.id.editText1);
}
}
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" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Main1" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:onClick="onClick"
/>
</LinearLayout>
mail2.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" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Main2" />
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2"
android:onClick="onClick"
/>
</LinearLayout>
Use a meta layout xml file with a structure similar to this one:
meta_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/root">
<include
layout="#layout/main" />
<include
layout="#layout/main2" />
</ViewFlipper>
And then main.java:
public class Main extends Activity implements View.OnClickListener {
EditText box1, box2;
ViewFlipper root;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.meta_main);
box1 = (EditText) findViewById(R.id.editText1);
box2 = (EditText) findViewById(R.id.editText2);
root = (ViewFlipper) findViewById(R.id.root);
}
public void onClick(View v) {
EditText editText = null;
switch (v.getId()) {
case R.id.button1:
editText = box1;
root.showNext();
break;
case R.id.button2:
editText = box2;
root.showPrevious();
break;
}
if(editText != null) {
Toast.makeText(this, editText.getText(), Toast.LENGTH_SHORT).show();
}
}
}
Hope it helps ;)
I don't think you can load a new layout that way.
Just put the two EditTexts in one XML and put one visible and the other invisble and with a button click vice versa.
As an alternative to different activities you might want to look at ViewFlipper http://developer.android.com/reference/android/widget/ViewFlipper.html
You are only allowed to call setContentView() once in your activity.
You can either
Create a "Main" layout that just contains a parent I.E. LinearLayout, or Relative layout
setContentView() on the parent. Then acquire a reference to it with findViewById() and call .addView() on your reference passing the inflated xml from one of these two files. .removeView() will allow you to switch to the other one when you like.
or
Include all of your views in one xml layout, but make half of them Visibility.GONE and when you want to switch just make the ones that were GONE be VISIBLE and vice versa
I think it should work, you have to reinitialize references for example every findViewById needs to be called again after calling setContentView(). You are exactly doing so first you are calling showXml1() & then you are clicking button1 which is executing Case1, you are getting the value of box1 & displaying it & then you are calling showXml2() & so on. I have tried your code & it works, i am wounding why its not working on your side?
Another thing is that it may not be a good idea if you have to call findViewbyId() a LOT OF TIMES, so you should avoid it i guess.