View.layout() works until next UI update - android

My launching activity consists of Linear layout with two buttons. Both buttons have listeners: the first one (b) moves itself upon click: 30px to the left and 30px back upon the next click.
The second one (b2) changes its text upon click. Here is the code:
public class TestActivity extends Activity {
public final String TAG="TestActivity";
boolean toTop=true;
boolean setInitialText=false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b=(Button)findViewById(R.id.button);
Button b2=(Button)findViewById(R.id.button2);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int modifier;
if(toTop) modifier=-30;
else modifier=30;
v.layout(v.getLeft()+modifier,v.getTop(),v.getRight()+modifier,v.getBottom());
toTop=!toTop;
}
});
b2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String currentText;
if(setInitialText)currentText="Press to change text";
else currentText="Press to change back";
((Button)v).setText(currentText);
setInitialText=!setInitialText;
}
});
}
}
XML layout-file:
<?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:gravity="center"
android:orientation="vertical" >
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press to begin animation" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press to change text" />
My problem: when b is moved to the left and I press b2, b moves to its initial position. Why? I don't want it to move back and didn't specify it anywhere.
It looks like View.layout looses its effect. Why it happens? I tested that in other situations and it seems that any UI update makes all invoked View.layout methods loose their effect.
In my main project there is a ListView which is populated with images from background - all view moves loose effect when new image appears. Besides, if I add EditText and try to enter something (as user), view moves loose their effect as well. Can anyone explain to me what's going on and why do views move back?

Looks like parent layout repositions it's siblings after you set a new text for the button2, because as describe in xml, button2 wraps it's content by width and height.
As you changed button's content, it requests it's parent layout to get a new position for it. In this case parent layout will recalculate position values for all of it's siblings. That's why button1 also comes back to it's previous position.
Keep in mind, that you also set the gravity value for parent layout as center, that means that when layout will position it's siblings it will position them in it's center.
Try to experiment with some ohter layout classes like FrameLayout, which has absolute manner of positioning it's siblings and RelativeLayout which and also try your case getting rid of layout's gravity.

Here says that this issue may be solved, using view.setLayoutParams() instead of view.layout()

Related

How to show another content over ViewPager?

I have the following problem:
I have MainActivity, where ViewPager is placed. Page of ViewPager is Fragment, which contains imageview and several textviews. When user clicks on the image, another content should be shown. And probably I don't understand how can I do it. As I know, I can't place FrameLayout on my Page Fragment and here show another fragment with needable content. Also I cannot place this fragment on MainActivity, as I cannot change it from my fragment (and if I want to change ViewPager on my Fragment with needable content, I cannot catch clicks on ImageView). I found one solution: to have 2 layouts on Page Fragment (first for ViewPager and second for content, which will be shown after), and change their visibility each time, but I don't think that this is the best idea. So, maybe you have better variants?
UPD
I need form this
after clicking on image get this:
you can use VeiwSwitcher wich you can learn about it here
public class ViewSwitcher extends ViewAnimator that switches between two views, and has a factory from which these views are created. You can either use the factory to create the views, or add them yourself. A ViewSwitcher can only have two child views, of which only one is shown at a time.
for example :
<ViewSwitcher
android:id="#+id/viewSwitcher1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:inAnimation="#android:anim/slide_in_left" >
<LinearLayout
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
//Content of first layout
</LinearLayout>
<LinearLayout
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
//Content of second layout
</LinearLayout>
</ViewSwitcher>
so basically you have Two ViewGroup and first one is visible to user and second one is hidden . and you can only have Two View in side of ViewSwitcher and you can switch between them with a Button :
viewSwitcher = (ViewSwitcher)findViewById(R.id.viewSwitcher1);
myFirstView= findViewById(R.id.view1);
mySecondView = findViewById(R.id.view2);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (viewSwitcher.getCurrentView() != myFirstView){
viewSwitcher.showPrevious();
} else if (viewSwitcher.getCurrentView() != mySecondView){
viewSwitcher.showNext();
}
}
});
and it dos not matter what kind of view or id used for those Two views.
so just put ViewSwitcher in your Fragment layout and put your image through xml or programmatically . and use Two Button one in the first layout and one in the second layout to switch between them. hope this works for you. you can also use Dialog but in your case it will make it ugly!

Android - propagating click from parent to child

I have a LinearLayout with a couple of TextViews stacked vertically. I want to attach a click listener to the parent and make the click event propagate to one of the TextViews (child views of the containing LinearLayout).
I understand that I can attach click listener's to the individual TextViews and achieve the same result but I'd like to do otherwise.
I came across the
android:duplicateParentState="true"
attribute, but this doesn't seem to solve the issue either. What should I be doing to get the child views to consume the containing parent's click event. Also each text view should perform a different action.
Here is the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text_1"
android:duplicateParentState="true"
android:layout_marginBottom="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:text="Text_2" />
</LinearLayout>
And here is the Activity:
public class MainActivity extends AppCompatActivity {
LinearLayout mLinearLayout;
TextView mTextView1;
TextView mTextView2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLinearLayout = (LinearLayout) findViewById(R.id.linear_layout);
mLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.v("view",view.toString());
}
});
}
}
The log always prints the parent view:
V/view: android.widget.LinearLayout{3ea32ab0 V.E...C. ...PH... 0,0-1080,1533 #7f0c0050 app:id/linear_layout}
V/view: android.widget.LinearLayout{3ea32ab0 V.E...C. ...PH... 0,0-1080,1533 #7f0c0050 app:id/linear_layout}
I am obviously missing something here and hopefully the solution doesn't involve navigating down the view stack. What am I doing wrong, any help would be most appreciated.
You may use setOnTouchListener for your LinearLayout. Inside this OnTouchListener you need to detect a click (GestureDetector can help) in this point you will have MotionEvent, you can get x,y coordinates from this event and compare them with your TextViews coordinates. So you can detect which TextView was clicked. In such a way you can do what you want, but it is complicated, and I believe you can avoid it.

Android: setX() or setTranslationX() does not change the position of adjacent view

I have 2 buttons in the following layout. Buttons are adjusted such that left button always remains to the left of right button
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/right_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right Button"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
<Button
android:id="#+id/left_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Left Button"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/right_btn"/>
</RelativeLayout>
But, In my activity, when I change the position of right button, the left button position remains same.
Button rightBtn = (Button) findViewById(R.id.right_btn);
rightBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
view.setTranslationX(100);
}
});
I have used both setTranslationX(100) as well as setX(500) to right button, but the left button position remains same. I am not sure but came to know that setTranslationX only change the appearance of button, but the object remains at the same position.
Is there any property to set the position of right button so that left button position also changes so that it is always to the left of right button.
when I change the position of right button, the left button position remains same.
That is because you explicitly moving the right button x-axis not the whole layout thus right button is only translated to the position you specify and not the left button as well.
Solution:
You can translate the left button as well when the right button is moved same translationx pixels.
I think one of the issues you seem to be having is that you're using
view.setTranslationX(100);
in a RelativeLayout which means you're kind of using it like an AbsoluteLayout (which in itself is deprecated).
Try to rethink your strategy.

LinearLayout's click listener is never called

Trying to get an onclick listener working on a linearlayout but its never called :(. Have enabled clickable and focsuable (both modes) and still cant get the click listener to respond. Platform details: Android 3.0.. Any help?? Code below
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menu_items_button"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center_horizontal"
android:paddingTop="#dimen/gen_margin_xsmall"
android:paddingBottom="#dimen/gen_margin_xsmall"
android:background="#drawable/rule_bg_menu_button"
android:clickable="true"
android:focusableInTouchMode="true"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/menu_items"
android:tag="image"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="text"
android:text="#string/menu_items_icon_txt"
style="#style/textDisplay.mediumLarge"
/>
</LinearLayout>
and in the code to add the event listener
_itemsButton = (LinearLayout) menu.findViewById(R.id.menu_items_button);
final Intent itemsIntent = new Intent(this, ItemsActivity.class);
_itemsButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(itemsIntent); //Never called!
}
}
);
The reason I'm doing this and not using an Image button instead is because the background of the "button" is state based (gradient changes) but also the image and in order to combine to the two on click / on focus, I used a linearlayout which has an ImageView in itself.. any suggestions on why the clickListener is not working on the linearLayout?
thx
Did the click go to the ImageView instead of the LinearLayout? Try clicking in the pad area (if any) or try putting the click listenner on the ImageView1.
(adding my response as a new answer so that I can use the PRE tag.)
The easy way is to set the same click listener on the image view and the text view.
View.OnClickListener activityLauncher = new View.OnClickListener() {... }
layout.setOnClickListener(activityLauncher);
imageView.setOnClickListener(activityLauncher);
textView.imageView.setOnClickListener(activityLauncher);
The width of your LinearLayout is set to "0dip", you should see nothing on the screen.
If the width is changed to "FULL_PARENT", that works. Please check your code carefully again.

EditText with cross(x) button at end of it

Is there any way to add the x-graphics in the android Editbox like the of iPhone
So that by clicking on that x graphic it can clear all the values in the Editbox
Is there any way to listen weather i touch a specific part of an edit text
Thank you
Yes there is a way to achieve this.
Define a RelativeLayout like this one.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText android:id="#+id/edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"/>
<ImageButton android:id="#+id/clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/icon"
android:layout_alignRight="#id/edittext"/>
</RelativeLayout>
Now what happens. The ImageButton gets drawn on top of the EditText. We set its right edge to be equal to the right edge of the EditTexts in order to get it appear on the right side.
Now you have to assign your ImageButton an OnCLickListener with if overridden method to just set the EditTexts text to a empty string like that.
EditText editText = null;
ImageButton clear = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clear);
editText = (EditText) findViewById(R.id.edittext);
clear = (ImageButton) findViewById(R.id.clear);
clear.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
editText.setText("");
}
});
}
Now here we simply tell our ImageViews OnClickListener to reset our EditTexts text upon a click. Simple as that. ;)
Of course my example uses not very aesthetic images but you can fine tune the images yourself. The principle works.
You can download it, it works like iPhone
https://github.com/GhOsTTT/editTextXbutton

Categories

Resources