Android: setting leftMargin property to a button automatically resizes it - android

I have a simple button in my layout. Setting leftMargin to the view actually showing different results.
my_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/left_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="hello pandora"/>
</RelativeLayout>
In my activity, I'm setting the leftMargin property to the Button.
Button leftBtn = (Button) findViewById(R.id.left_btn);
LayoutParams params = (LayoutParams) leftBtn.getLayoutParams();
params.leftMargin = 550;
If I set leftMargin as negative value or 0, its working fine, but If I set the value greater than the width of screen, it just resizing/compressing the button. I am expecting the button to go out of bounds like negative value.
I am expecting the button in the 3rd image to go out of bounds like the button in 1st image.
Please don't say to set the button layout_alignParentRight="true" in layout and rightMargin = -50in activity(this works) because I want to move the button from left to right.

I assume assigning a specific width larger than the screen size (eg. 1000 dp) to the parent RelativeLayout should solve your problem.
Also why do you want to make out-of-screen UI elements? What is the desired behaviour? Perhaps a transition animation would be better?
EDIT
I've tried the animation + storing the measured width of the Button. It seems to work.
Can you try this on GB?
MainActivity.java
public class MainActivity extends Activity {
final Context context = this;
Button mButton;
int mButtonWidth; // Measured width of Button
int amountToMove; // Amount to move the button in the x direction
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
amountToMove = 600;
mButton = (Button) findViewById(R.id.button);
// Measure Button's width
mButton.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
mButtonWidth = mButton.getMeasuredWidth();
// Simple onClick listener showing a Toast
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,"Hello Pandora clicked!",Toast.LENGTH_SHORT).show();
}
});
// Onclick listener for the other button
Button toggle = (Button) findViewById(R.id.toggle);
toggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Animate the other button
TranslateAnimation a = new TranslateAnimation(0, amountToMove, 0, 0);
a.setDuration(1000);
// Finalize movement when animation ends
a.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)mButton.getLayoutParams();
// Restore measured width and change left margin
lp.width = mButtonWidth;
lp.leftMargin = lp.leftMargin + amountToMove;
mButton.setLayoutParams(lp);
amountToMove = -amountToMove;
}
#Override
public void onAnimationStart(Animation animation) { /* Do nothing */ }
#Override
public void onAnimationRepeat(Animation animation) { /* Do nothing */ }
});
mButton.startAnimation(a);
}
});
}
}
activity_main.xml
<LinearLayout 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"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello Pandora"
android:id="#+id/button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Move the other button"
android:id="#+id/toggle"/>
</LinearLayout>
EDIT 2
It works on a GB Emulator too (the Button gets clipped, is clickable).

u can use max line=1 to show complete text in one line on button when you use leftMargin = 550;
try this
<Button
android:id="#+id/left_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:maxLines="1"
android:text="hello pandora"/>

Hello Edit your button property like this,
android:layout_gravity="center_horizontal"
android:singleLine="true"
and change parent layout to frameLayout

Related

setLayoutParams called from button OnClickListener

I'm trying to resize ImageView on button click. I don't know why but setLayoutParams works when I call it in onCreate method, but not working when use it inside button's OnClickListener. Did I miss something?
ImageView myImageView;
Button myButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
myImageView = findViewById(R.id.viewtest);
myButton = (Button)findViewById(R.id.buttontest);
resizeImageView(); // resize when called here
myButton.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
resizeImageView(); // NOT resize when called here
}
});
}
private void resizeImageView() {
Toast.makeText(getApplicationContext(), "Resize", Toast.LENGTH_LONG).show();
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)myImageView.getLayoutParams();
params.height = 300;
params.width = 300;
myImageView.setLayoutParams(params);
}
XML layout. I'm using LinearLayout inside of RelativeLayout.
<?xml version="1.0" encoding="utf-8"?>
<android.widget.RelativeLayout 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"
tools:context=".ResultActivity">
<android.widget.LinearLayout
android:id="#+id/lineartest"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:id="#+id/viewtest"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="centerCrop"
android:layout_centerVertical="true"
app:srcCompat="#mipmap/ic_launcher_round"
android:background="#444"
/>
</android.widget.LinearLayout>
<android.support.v7.widget.AppCompatButton
android:id="#+id/buttontest"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="test"/>
</android.widget.RelativeLayout>
I just checked. This works fine in case of ImageView.
Maybe you are resizing it multiple times. Means If you have already called resresizeImageView() in onCreate method and you call it again in OnClick method , the resizing won't be visible because it already has the size you are resizing to.
In xml, you have AppCompatButton but in java you have defined as Button. Change AppCompatButton to Button in xml Or in java, Button to AppCompatButton.
I used your code, to create a new project, and just commented out the first call to resizeImageView() and it works fine when resizeImageView() is called in onClick()
As Derek answered, maybe you're already setting the same bounds to the ImageView during onCreate() which you wish to update in button click.
Also, just a suggestion:
Try adding the property android:layout_below="#id/lineartest" to your AppCompatButton.
Change android:layout_height="wrap_content", so you can view the changes happening to the ImageView.
Try this one
public class SomeActivity extends Activity {
public static final float screenWidth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.the_company);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
}
}
And after declare this implementation:
Button mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
float scale = SomeActivity.screenWidth / view.getWidth();
if(view.getScaleX() == 1) {
view.setScaleY(scale);
view.setScaleX(scale);
} else{
view.setScaleY(1);
view.setScaleX(1);
}
}
});
OK. I've found solution. I use some async task that affects ImageView (loading image). When I disabled it resize button started to work as excepted. Thanks for your help.

Moving buttons at desired locations

I have this problem: I want to put some Buttons at a certain locations, for example at the four squares of the screen (resolved) and I also want them to become red when clicking on each one, at exactly those locations (not resolved yet).
This is the main xml:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_weight="15"
android:orientation="vertical">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:components="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/layout1">
<Button
android:id="#+id/one"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#color/colorPrimary"/>
<Button
android:id="#+id/two"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentEnd="true"
android:background="#color/colorPrimary" />
<Button
android:id="#+id/three"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#color/colorPrimary" />
<Button
android:id="#+id/four"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:background="#color/colorPrimary"/>
</RelativeLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
And this is the main java:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout1);
RelativeLayout.LayoutParams rel_btn = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
Button btnTag = new Button(this);
btnTag.setLayoutParams(rel_btn);
btnTag.setBackgroundColor(Color.BLUE);
btnTag.setOnClickListener(listen);
layout.addView(btnTag);
}
private View.OnClickListener listen = new View.OnClickListener() {
#Override
public void onClick(View view) {
if (pressed != null) {
Button button1 = (Button) pressed;
button1.setBackgroundColor(Color.BLUE);
}
Button button2 = (Button) view;
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setStroke(8, Color.RED);
button2.setBackgroundDrawable(drawable);
pressed = view;
}
in onCreate set up your buttons:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout1);
RelativeLayout.LayoutParams rel_btn = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
Button one = (Button) findViewById(R.id.one);
one.setOnClickListener(listen);
Button two = (Button) findViewById(R.id.two);
two.setOnClickListener(listen);
Button three = (Button) findViewById(R.id.three);
three.setOnClickListener(listen);
Button four = (Button) findViewById(R.id.four);
four.setOnClickListener(listen);
and finally create your listener for all 4 of the buttons:
private View.OnClickListener listen = new View.OnClickListener() {
#Override
public void onClick(View view) {
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setStroke(8, Color.RED);
Button button = (Button) view;
button.setBackground(drawable);
}
};
If you were created Buttons in the layout then why are you adding it dynamically.
If you are using layout then inflate these buttons using "findViewById()". And when user will click perform the action to that or all buttons.
one.setBackgroundColor(Color.RED);
But if you are using dynamic button creation then store all 4 button id's which you are creating. Then perform something like this.
buttonId[index].setBackgroundColor(Color.RED);
Make your main class implement to View.OnclickListener
public class MainFragment extends Fragment implements View.OnClickListener {
private void setUpViews() {
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
button4.setOnClickListener(this);
}}
#Override
public void onClick(View view) {
if(view instance of Button){
button.setBackgroundColor(getResources().getColor(android.R.color.holo_red_dark));
}
}
}
Well, if you give those buttons IDs, then you can change the color of them when you click it.
So if you tap on buttonID, do your logic and then change the color to buttonID.
// If you're in an activity:
buttonID.setBackgroundColor(getResources().getColor(R.color.red));
Add the color red to your color xml.
this can go inside of your onCreate. the buttonOne and buttonTwo at the IDs to the buttons in your XML.
This is the most BASIC way to do it. There are more ways, you can see those answers here too.
buttonOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//logic here
}
});
buttonTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//logic here
}
});
When you have a listener changing something is relatively easy. You do not need to implement different methods or check every button one by one. Since Button is a View as well, do the following pseudo-code.
// You need this if part, if you have other views that having the same listener.
// Otherwise, you do not need this if check.
if(is Clicked View is Button) {
// Now here, take the clicked view, which we know it is a button and change its colour.
}
By the way, the code above will be inside the overridden method onClick.
EDIT
To clarify, I am adding a small chunk of code.
#Override
public void onClick(View view) {
// Checking if the clicked View is a Button or not.
if(view instanceof Button) {
// view.getId() returns an integer.
Button clickedButton = (Button) findViewById(view.getId());
// Now, change the button's colour.
clickedButton.setBackground(........);
}
}
Hope it helps. Have a nice day!

Button disappears when increasing its height

I try to create square buttons. When increasing the button's height, it disappears. However, when increasing it's width, everything works fine. What's going on there?
private void adjustButtons() {
final Button trainerButton = (Button) findViewById(R.id.bu_vocabulary_start_trainer);
trainerButton.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View arg0) {
ViewGroup.LayoutParams params = shareButton.getLayoutParams();
// params.width++; // works fine
params.height++; // button disappears
// params.height = params.width; // what I acutually want to do
shareButton.setLayoutParams(params);
}
});
}
The xml file
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="30dp"
android:orientation="horizontal" >
<Button
android:id="#+id/bu_vocabulary_start_trainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/vocabulary_trainer" />
<Button
android:id="#+id/bu_vocabulary_start_administration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/vocabulary_administration" />
</LinearLayout>
try this,
private void adjustButtons() {
final Button trainerButton = (Button) findViewById(R.id.bu_vocabulary_start_trainer);
trainerButton.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View arg0) {
LinearLayout.LayoutParams params = shareButton.getLayoutParams();
// params.width++; // works fine
params.height++; // button disappears
// params.height = params.width; // what I acutually want to do
shareButton.setLayoutParams(params);
}
});
}
you should use dp number for your height and weight.
height++ doesn't work for wrap_content
First of all, WRAP_CONTENT is just an integer value, which maps to -2. Increasing it would change it to -1, which is MATCH_PARENT.
You see the situation now? Your LinearLayout has height WRAP_CONTENT. This means "make its height as large as need be to contain its children". If the children are set to MATCH_PARENT, that would mean "make them as large as their parent". This situation is resolved by making both parent and children 0 pixels high. Hence, they "disappear".
What you could do, though, is something like:
params.height = shareButton.getHeight() + 1;
This line might help you:
button.setLayoutParams (new LayoutParams(LayoutParams.WRAP_CONTENT, yourheight++);

Slide image from left to right and right to left

I am developing an application in which I want to add image which can slide from left to right and from right to left like below image. That inner white play image should be move from left to right and Vice Versa.
What I have did so far is, I am able to move single image from left to right and vice versa but I want set background image as well like above rounded shaped black background.
Here is my code:
imageView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int eid = event.getAction();
switch (eid) {
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams mParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
int x = (int) event.getRawX();
mParams.leftMargin = x - 50;
imageView.setLayoutParams(mParams);
break;
default:
break;
}
return true;
}
});
EDIT
I tried to manage background image by setting my layout xml like below:
<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" >
<RelativeLayout
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="49dp"
android:background="#drawable/set_user_profile_back"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/hello_world"
android:src="#drawable/next" />
</RelativeLayout>
</RelativeLayout>
But now I am facing problem with image size, image size is decreased in right how to solve this and how to fix start and end point for image movement.
Any idea and advice will be apppreciated
Can you please try this piece of code Juned
public class MainActivity extends Activity {
Button b1;
ImageView logo;
float width;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.button1);
logo = (ImageView) findViewById(R.id.logo);
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
final Animation posX = new TranslateAnimation(0, width - 50, 0, 0);
posX.setDuration(1000);
posX.setFillAfter(true);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
logo.startAnimation(posX);
logo.setVisibility(View.VISIBLE);
}
});
}}

Moving widgets in runtime on Android

I have a simple demo with two buttons. They are laid out with a RelativeLayout at the top and bottom of the screen.
When I click one of them, I want them to switch places.
What is the best way to do that?
This is my res/layout/main.xml :
<?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="fill_parent">
<ImageButton
android:id="#+id/android_button_1"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:src="#drawable/icon"
android:layout_alignParentTop="true" />
<ImageButton
android:id="#+id/android_button_2"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:src="#drawable/icon2"
android:layout_alignParentBottom="true" />
</RelativeLayout>
And this is my Activity:
public class HelloButtons extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ImageButton button1 = (ImageButton) findViewById(R.id.android_button_1);
final ImageButton button2 = (ImageButton) findViewById(R.id.android_button_2);
button1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
Toast.makeText(HelloButtons.this, "Beep Bop", Toast.LENGTH_SHORT).show();
}
});
button2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
Toast.makeText(HelloButtons.this, "Beep Bop", Toast.LENGTH_SHORT).show();
}
});
}
}
Use something along these lines
RelativeLayout.LayoutParams lp1 = (LayoutParams) b1.getLayoutParams();
RelativeLayout.LayoutParams lp2 = (LayoutParams) b2.getLayoutParams();
lp2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
lp2.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
lp1.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
lp1.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
b1.setLayoutParams(lp1);
b2.setLayoutParams(lp2);
(and the opposite to revert them again) in you OnClickListeners
I would say the best way to do that is not to switch the actual ImageButton locations, but to instead switch the ImageButton images and keep track of the state inside your application so it can react to onClicks correctly.

Categories

Resources