I have a RelativeLayout inside of a ScrollView that contains a Button and some TextViews and EditTexts.
In my xml layout file, I am defining android:onClick but it always takes two clicks of the button to fire the event. The button always gets the focus on the first click and fires the onClick event on the second click. I have tried setting focusable and focusableInTouchMode both to false but the behavior doesn't change.
Here is my layout file:
<ScrollView 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:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".DensityActivity" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
...
<TextView
...
<TextView
...
<EditText
...
<Button
android:id="#+id/ad_button_calculate"
android:layout_width="112dp"
android:layout_height="wrap_content"
android:layout_below="#id/ad_edit_obs_temp"
android:layout_alignParentRight="true"
android:layout_marginTop="20pt"
android:paddingLeft="6pt"
android:onClick="onClick"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="#string/button_calculate" />
<TextView
...
</RelativeLayout>
</ScrollView>
Any ideas or suggestions as to why the focusable and focusableInTouchMode don't seem to do anything?
I thought it might be my onClick() method not doing what it should so I reduced it to something simple just to see and it behaves the same. Here is my simplified onClick():
public void onClick(View view) {
new AlertDialog.Builder(this).setTitle("Argh").setMessage("Watch out!").setNeutralButton("Close", null).show();
}
OK, I found it. It was, of course, my own mistake.
At the end of my onCreate method I was doing this:
// Set the focus to the calculate button so the keyboard won't show up automatically
Button calcButton = (Button)findViewById( R.id.ac_button_calculate );
calcButton.setFocusable( true );
calcButton.setFocusableInTouchMode( true );
calcButton.requestFocus();
So of course, no matter what I did in my xml file, I was overriding it in my code.
Instead, I used this to hide the keyboard:
getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN );
Which works great.
Related
I have two views one is a button and the other is LinearLayout.
When i set View.GONE and then to View.VISIBLE the view wont get visible again.
This mechanism was working in the past.
android:id="#+id/selector_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#drawable/shape_round_white_1"/>
<include
android:id="#+id/actions_container"
android:layout_width="match_parent"
android:layout_height="48dp"
layout="#layout/wait_request_accept_panel"
android:visibility="visible"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="#id/selector_controls"
android:layout_alignEnd="#id/selector_controls"
android:layout_alignLeft="#id/selector_controls">
Now... what i want is to toggle is the elements inside wait_request_accept_panel this is the layout file, I want to toggle elements inside it..
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RelativeLayout
android:id="#+id/wait_container"
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#drawable/shape_round_white_1">
<!-- Other view elements -->
</RelativeLayout>
<Button
android:id="#+id/btnAccept"
android:layout_width="match_parent"
android:layout_height="48dp"
style="#style/H18b"
android:visibility="visible"
android:background="#drawable/shape_round_white_1"
android:text="#string/str_accept"
android:layout_alignParentTop="true"/>
</RelativeLayout>
As you can se here there is two elements basically a wait_container which shows up when user is waiting, and a Button btnAccept it only change state once: one in the original state which is, wait_container is GONE and button Button which is visible at first time. When I hit btnAcceptthe btn changes to GONE and the wait container changes to VISIBLE
Here is the programatic impementation:
switch (req.getType()) {
case REQ: // this is the initial flow
waitContainer.setVisibility(View.GONE);
acceptBtn.setVisibility(View.VISIBLE);
break;
case ACCEPT: // after hit the accept btn it toggles the two views
acceptBtn.setVisibility(View.GONE);
waitContainer.setVisibility(View.VISIBLE);
break;
}
Init details
waitContainer = (RelativeLayout) view.findViewById(R.id.wait_container);
acceptBtn = (Button) view.findViewById(R.id.btnAccept);
cancelBtn = (Button) view.findViewById(R.id.btnCancel);
Something to take in count is the fact the waitContainer and acceptBtn are included, they came from another xml file, I did that because I wanted to reuse code, but in this moment that's not so important since the current screen is the only that uses the wait_request_accept_panel.xml file.
SOLUTION
The view were always there, but it's alpha channel was modified by an animation when the fragment was starting, I sent by mistake the viewContainer as a parameter to the animation method which i turns animates its alpha channel.
You can try with getVisibility ().
Returns the visibility status for this view.
if(waitContainer.getVisibility()== View.GONE)
{
acceptBtn.setVisibility(View.GONE);
waitContainer.setVisibility(View.VISIBLE);
}
Check the visibility of view after that apply ViSIBLE/GONE have look
if(waitContainer.getVisibility()== View.GONE)
{
waitContainer.setVisibility(View.VISIBLE);
}else{
waitContainer.setVisibility(View.GONE);
}
1.This is the activity I'm calling
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_contacts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:padding="0dp"
tools:context="com.example.hangout1.contacts">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="0dp"
android:layout_margin="0dp">
<SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="60dp"
android:queryHint="Enter a name or number"
android:iconifiedByDefault="true"
android:inputType="text"
/>
</LinearLayout>
</FrameLayout>
2.This is how I'm calling it
public void loadContacts(View view){
Intent intent = new Intent(GroupMembersActivity.this,contacts.class);
startActivity(intent);
}
I'm new to android. When attribute 'iconifiedByDefault' is set to 'true' and if I'm not touching the search icon(not expanding), touching the back button once takes me back to the previous activity(the one called this activity). But if it is set to 'false' it takes two touches on back button to go back to the previous activity. Please let me know a little insights on this behavior. Thank you
The searchview is by default set to focusable=true, which means the query area in the search view was active, like ready for text to be entered. so it took one touch to exit from the focus and one for the activity to go back. when I set the attribute focusable to false, query area is not ready now and is ready only when touched. so one tap less. Here's what I did
android:focusable="false"
I have 2 layouts which contain the same buttons
layout_1.xml
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button_1"
android:text="button2"
android:background="#android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
and
layout_2.xml
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button_1"
android:text="button2"
android:background="#android:color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Please assume these are all valid layouts etc.(I am just adding the relevant code.).
So in my fragment ,I inflate and use layout_1.xml in onCreateView.I want to toggle between the 2 scenes using button_1.
I can set the listener for button_1 in layout_1.xml during the onCreateView().
The problem is trying to set a listener on that button in the second view.i.e. the listener does not activate for the second scene(with layout_2.xml).And hence i canot toggle between the 2 scenes.Is there a way to achieve this?
It would actually appear that a proper way to do this would be to on the second scene you define an action to be performed as such:
mSecondScene.setEnterAction(new Runnable() {
#Override
public void run() {
((Button) mSecondScene.getSceneRoot().findViewById(R.id. button_1)).setOnClickListener( ... );
}
This will allow you to set your ClickListener on the View without the data binding to a generic click listener method. Then you can perform the Transition to the second scene and viola.
In general, it is not a good idea to have multiple views with the same id. This is what caused the confusion here.
Note: Below is the solution used by OP that was suitable for their specific needs:
One simple solution is to use the onClick attribute in the XML file. You can assign the same onClick method to multiple items. Like this:
And in your activity.java add this:
public void buttonClicked(View v){
Log.d("TAG","Button clicked!!"
// do stuff here
}
2nd option:
When you set a listener for one button with the id of button_1, it does not set the listener for both buttons, it only sets it for the first one. If you want to set the same listener for both, all you need to do is to assign these button different ids and then assign them the same listener.
This is what you should do:
Listener myListener = new Listener(){.. blah blah....};
((Button) findViewById(R.id.some_id)).setListerner(myListener);
((Button) findViewById(R.id.some_other_id)).setListerner(myListener);
3rd option:
findViewById(R.id.id_of_layout1).findViewById(R.id.button_1)
findViewById(R.id.id_of_layout2).findViewById(R.id.button_1)
in this case, you need add some id to your layout files, for example: layout_1.xml:
<RelativeLayout
android:id="+id/id_of_layout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button_1"
android:text="button2"
android:background="#android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
I've got a ListView with several rows. Every row consists of 7 TextViews which react to onClick() events.
This all works perfectly fine but when the user clicks on the margins of the row, where no TextView catches the onClick() event, the root view - a LinearLayout - get's highlighted.
This is normal behaviour of course but as nothing happens by clicking there I don't want the Linear Layout to be highlighted.
Is there any way of disabling this behaviour but keep catching the onClick() events on the TextViews?
(The onClick listener is set inside the adapters getView() method)
Here some extract of the xml file. As one can see I've tried some things but they don't work.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:longClickable="false"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false">
<TextView
android:id="#+id/listelement_weekoverview_tv_mo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="1dp"
android:layout_weight="1"
android:background="#drawable/weeklylist_rndrectangle"
android:gravity="center_horizontal"
android:singleLine="false"
android:textColor="#color/appcolor_red_base" />
...
</LinearLayout>
unclicked version
clicked version
I've found a solution.
Simply overwrite the isEnabled (int position) method in your custom Adapter like this:
#Override
public boolean isEnabled (int position) {
return false;
}
I have a EditText(searcField) in a android dialog, after I finished the editing, and dismiss the dialog.
then i go to other EditText, the focus is still in searchField.
Any idea?
thanks
EDIT:
there are too much to post in here, hope this can help a bit to understand my issue.
Customer dialog view
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:orientation="horizontal" >
<EditText
android:id="#+id/search_field"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="left"
android:inputType="textNoSuggestions|textVisiblePassword"
android:layout_weight="0.70"
android:hint="type item name to search"/>
</LinearLayout>
<ListView
android:id="#+id/itemList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#00000000"
android:descendantFocusability="beforeDescendants"
android:scrollbars="none"/>
</LinearLayout>
Java code
View searchView = getActivity().getLayoutInflater().inflate(R.layout.search, null, false);
EditText searchField = (EditText)productEditView.findViewById(R.id.search_field);
searchField.addTextChangedListener(this);
...
public void afterTextChanged(Editable text) {
if (searchField.hasFocus()) {
Log.i("MyApp", "searchField is still focused");
return;
}
if (otherField.hasFocus()){
Log.i("MyApp", "other field");
return;
}
}
Another, albeit somewhat hacky, solution I regularly use is setting android:focusable="true" and android:focusableInTouchMode="true" to the parent view (LinearLayout, RelativeLayout, etc) of a layout if I want to be able to clearFocus() of an EditText, or open the Activity/Fragment without the first EditText from being focused automatically.
I don't know if it can be achieved through xml but you can do it programmatically when your dialog is dismissed by doing something like:
mView.setFocusableInTouchMode(true);
mView.requestFocus();
To know when your dialog is dismissed simply override the onDismiss() callback method.
You have to add the following code after your editing code event :
seachview.clearfocus();
edittext.requestfocus();