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++);
Related
I need to have 2 buttons which wrap content but always stay same equal in width.
I want BUTTON 1 stretch to the width of BUTTON 2. Or if BUTTON 1 Would be wider I would need BUTTON 2 to stretch to the width of BUTTON 1
How can I achieve this? I tried using LinearLayout with weights, but it only works if linear layout width matched parent, which makes buttons unnecessary wide.
To make both the button identical you have to calculate width of both the button like this
ViewTreeObserver vto1 = button1.getViewTreeObserver();
vto1.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
width = button1.getWidth();
height = button1.getHeight();
}
});
ViewTreeObserver vto2 = button2.getViewTreeObserver();
vto2 .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
width = button2.getWidth();
height = button2.getHeight();
}
});
then compare both the button height and set the larger one to both the buttons.
Try this!!! This may help...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 2"/>
</LinearLayout>
This will give the output as,
Use Linear Layout Weight Attribute
First Enclose Both Buttons In Linear Layout And give them horizontal orientation.
Then Give Them Equal Weights
android:layout_weight="1"
Try This Result
While Ajay's answer is right, but it requires you to remove the listener once you are done with it.
ViewTreeObserver vto2 = button2.getViewTreeObserver();
vto2 .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
width = button2.getWidth();
height = button2.getHeight();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
myView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
else {
myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
I'm answering an old question, but there exist a one line solution.
Add android:layout_width="0dip" to both (i.e. all) buttons definitions in .xml file.
Another (alternative) solution is to add android:layout_width="fill_parent" to both (all) buttons definitions.
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
I have a layout which at start has '0dp' width but when a button is clicked it animates from Left to right and its width is increased accordingly. In this layout I am initializing a custom view. The view is initialized correctly when I place it at right or at centre but when I place it on the left it's not shown.
Here is my XML:
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0"
android:background="#drawable/bg">
<com.example.Wheel
android:id="#+id/wheel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" >
</com.example.Wheel>
</RelativeLayout>
And here is what I do in java:
MenuListLeft = (RelativeLayout) findViewById(R.id.ControlLayout);
openButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (isExpandedLeft) {
isExpandedLeft = false;
MenuListLeft.startAnimation(new CollapseAnimationLTR(MenuListLeft, 0,(int)(screenWidth*1), 5));
}
else {
isExpandedLeft = true;
MenuListLeft.startAnimation(new ExpandAnimationLTR(MenuListLeft, 0,(int)(screenWidth*1), 5));
init();
}
}
});
You would be better of using weights in a combination of Relative and Linear Layout rather than just in a Relative Layout.
Here...
weight = 0 gets you no space expansion. Try setting it to 1.
In case you want to understand more on how weight works:
http://teamdroid.wordpress.com/2012/06/06/android-layout-weight-explained/
Also, for your case, wouldn't a View.Visibility GONE, VISIBLE...with animation may work better.
I need to be able to rotate whole layouts on the fly (on the click of a button).
I am able to rotate the layouts using, eg. layout.setRotation(270.0f). The problem is, after the rotation, the layout height and width are not matching its parent's.
I have tried inverting height and width like so,
RelativeLayout layout = (RelativeLayout)findViewById(R.id.rootLayout);
LayoutParams layoutParams = layout.getLayoutParams();
int height = layout.getHeight();
int width = layout.getWidth();
layoutParams.height = width;
layoutParams.width = height;
Which does nothing at all.
I am working with sdk 14.
The first image below is the app as it starts. The second one, after a rotation. I wish to fill the black "space". Any help would be appreciated.
The images below show only a button in the layout. However, in reality, the layout are a lot more complex. What I am trying to achieve is "faking" a landscape view.
Edit: Changed images and added descriptions.
Not sure why this is useful, but it's a nice puzzle. Here is something that works for me:
On rotate click, do this:
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main);
int w = mainLayout.getWidth();
int h = mainLayout.getHeight();
mainLayout.setRotation(270.0f);
mainLayout.setTranslationX((w - h) / 2);
mainLayout.setTranslationY((h - w) / 2);
ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) mainLayout.getLayoutParams();
lp.height = w;
lp.width = h;
mainLayout.requestLayout();
And the layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="#+id/main"
android:layout_height="match_parent"
android:background="#ffcc88"
tools:context=".TestRotateActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<Button
android:id="#+id/rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rotate"
android:layout_centerInParent="true"
/>
</RelativeLayout>
Try this code:
btnRotate.setOnClickListener(new OnClickListener()
{
#SuppressLint("NewApi")
#Override
public void onClick(View v)
{
int orientation = getResources().getConfiguration().orientation;
switch(orientation)
{
case Configuration.ORIENTATION_LANDSCAPE:
llparent.setRotation(270.0f);
RelativeLayout.LayoutParams layoutParams_LandsScape =
new RelativeLayout.LayoutParams(
rlRoot.getHeight(), rlRoot.getWidth());
layoutParams_LandsScape.setMargins(
rlRoot.getTop(), rlRoot.getRight(),
rlRoot.getBottom(), rlRoot.getLeft());
layoutParams_LandsScape.addRule(RelativeLayout.CENTER_IN_PARENT);
llparent.setLayoutParams(layoutParams_LandsScape);
break;
case Configuration.ORIENTATION_PORTRAIT:
llparent.setRotation(270.0f);
RelativeLayout.LayoutParams layoutParams_Portrait =
new RelativeLayout.LayoutParams(
rlRoot.getHeight(), rlRoot.getWidth());
layoutParams_Portrait.setMargins(
0, 0, rlRoot.getBottom(), rlRoot.getLeft());
layoutParams_Portrait.addRule(RelativeLayout.CENTER_IN_PARENT);
llparent.setLayoutParams(layoutParams_Portrait);
break;
}
}
});
}
And XML:
<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"
tools:context=".RotateAnim">
<RelativeLayout
android:id="#+id/rlroot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#090">
<LinearLayout
android:id="#+id/llParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#900"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Button"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
Simple and tricky way to make screen orientation along the button click.. with an example..
Here,I'm using the sharedPreference(Im setting an boolean value based on orientation )
Method for button onClick.
public void rotate(View v) {
edt = prefs.edit();
if (!prefs.getBoolean("screen_protrait", true)) {
edt.putBoolean("screen_protrait", true);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
edt.putBoolean("screen_protrait", false);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
edt.commit();
}
In xml, set an onClick method for rotate button
<Button
android:id="#+id/bt_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="rotate"
android:text="Rotate" />
Last one, is in onCreate of Activity you want to set the Prefernce from Application..as
prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Keep coding.. You can achieve your goal...Let me know,if it's working with your scenario.
If you want to literally rotate the screen, you can force a screen orientation.
Otherwise there's no easy way to do what you are trying to do as View.setRotation(float) will always render the View in its "real" bounds and then rotate it! What I suggest is careful consideration of what elements of the layout should be rotated and then to rotate those specifically.
The only true "automatic" way of achieving it would be to create a custom layout that essentially measures, layouts and draws children rotated... Honestly I would only go there if I really, really needed to and it's probably more trouble than it's worth!
// get root layout from activity's XML
LinearLayout mParentLayout = (LinearLayout) findViewById(R.id.activity_main);
// get screen size from DisplayMetrics if you need to rotate before the screen is shown
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
// if you are rotating after the view was shown
// acquire width and height from the layout's parent's LayoutParams
// calculate offset to move the view into correct position
int offset = (width - height) / 2;
// rotate the layout
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(height, width);
mParentLayout.setLayoutParams(lp);
// 90° clockwise
mParentLayout.setRotation(90.0f);
mParentLayout.setTranslationX(offset);
mParentLayout.setTranslationY(-offset);
It may look like the suggested answer, but this displays how to get dimensions from DisplayMetrics and the calculating the offset for the translation is a little different because that's the only way it worked properly.
i'll suggest you rotate only button rather than rotating the whole layout like
btn_rotate.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
rotation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate);
rotation.setFillAfter(true);
btn_rotate.startAnimation(rotation);
}
});
rotate.xml
<set>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="0"
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:toDegrees="270" />
</set>
try set your layout params to match_parent after rotation:
layout.setRotation(270.0f)
and then
RelativeLayout layout = (RelativeLayout) findViewById(R.id.rootLayout);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
EDIT: get the parentView View parent = layout.getParent(); and set the width and height of the parent view to your layout as you need - in width to height and vice versa.
Android: alternate layout xml for landscape mode
As I can remember, you should define a new layout for the horizontal view. I think this link can help you
Try this code:
(RelativeLayoutOuterFrame) it is the name of your layout.which you want to rotate.
Actually, we are not rotate the layout.we just change height an width value.
int w = RelativeLayoutOuterFrame.getWidth();
int h = RelativeLayoutOuterFrame.getHeight();
ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) RelativeLayoutOuterFrame.getLayoutParams();
lp.height = w;
lp.width = h;
RelativeLayoutOuterFrame.setGravity(RelativeLayout.CENTER_IN_PARENT);
RelativeLayoutOuterFrame.setGravity(RelativeLayout.CENTER_HORIZONTAL);
RelativeLayoutOuterFrame.requestLayout();
Another weird behavior encountered here. This time my dialog is shrinking width wise inspite of setting all parent layout's width as fill_parent. Here is the image...
I have tried making it an activity with theme set as Dialog in manifest. Still it is behaving same. However it becomes normal as soon as I set layout_width for first TextView "User Agreement" as fill_parent. But I don't understand this behavior as it should not depend on TextView's width for its own width. Please tell me if there is any other efficient way to deal with these type of situations. My code for layout is below:
<?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:background="#layout/gradientback"
android:orientation="vertical" >
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="User Agreement"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#B80303" />
<View
android:layout_width="fill_parent"
android:layout_height="3dip"
android:background="?android:attr/listDivider" >
</View>
<LinearLayout
android:id="#+id/linearLayout4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<CheckBox
android:id="#+id/checkBoxForTermsId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#7B4302"
android:text="I Agree The Terms & Conditions" >
</CheckBox>
This is not whole code for layout because I don't think it is needed...
The code for showing Dialog is as follows:
private void showAgreementBox() {
// TODO Auto-generated method stub
final Dialog dialog = new Dialog(Launcher.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.useragreement);
dialog.setTitle("User Agreement");
dialog.setCancelable(false);
final TextView userAg = (TextView) dialog.findViewById(R.id.textViewOfUserAg);
final CheckBox checkUserAg = (CheckBox) dialog.findViewById(R.id.checkBoxForTermsId);
final Button continueB = (Button) dialog.findViewById(R.id.continueB);
checkUserAg.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (checkUserAg.isChecked() == true) {
continueB.setEnabled(true);
} else {
continueB.setEnabled(false);
}
}
});
continueB.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
dialog.dismiss();
//checkForTrialPeriod(isUserRegisterd);
}
});
Button cancelB = (Button) dialog.findViewById(R.id.cancelB);
cancelB.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
dialog.show();
}
Fix the width of your parent layout
android:layout_width="400dp"
fill_parent works for Activity xml but for dialogs you have to set the width.
If you are looking for a general solution set an image as background in the parent layout just like we place images in different drawable folders to support multiple screens.
You can also set width as full screen using
dialog.getWindow().getAttributes().width = LayoutParams.FILL_PARENT;
Why this behavior is shown by dialog (quoting from this post by Dianne Hackborn)
The dialog theme, as part of its nature, sets the top-level window
layout to be WRAP_CONTENT. You could try manually setting the Window
layout width and height to FILL_PARENT [...]
Also took reference from this answer.
setContentView(R.layout.layout_name);
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
this worked for me .