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();
Related
I want to wrap an ImageView inside a LinearLayout so that I can center a group of views. However, the original image needs to be scaled down to fit in the ImageView, and the original size expands the LinearLayout, despite my use of adjustViewBounds="true" and an enclosing FrameLayout as suggested by previous questions on SO.
The desired layout should look like this,
but the observed layout looks like this,
as produced by the XML below:
<android.support.percent.PercentRelativeLayout
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="project.MainActivity">
<LinearLayout
android:layout_width="wrap_content"
app:layout_heightPercent="32%"
android:orientation="horizontal"
android:background="#b44343"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample Text"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#5555ae">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#2c8c4c"
android:src="#drawable/spades_icon"
android:adjustViewBounds="true"
android:scaleType="centerInside"/>
</FrameLayout>
</LinearLayout>
</android.support.percent.PercentRelativeLayout>
I can't use the other suggestion of setting android:maxHeight="100dp" because I need the height to be relative to that of the screen.
I see that you have added android:adjustViewBounds="true".
You can combine that with android:maxWidth="60dp"
So your imageView should look like this.
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#2c8c4c"
android:src="#drawable/spades_icon"
android:adjustViewBounds="true"
android:maxWidth="60dp"
android:scaleType="centerInside"/>
You can change the max width to any number you want.
Things you can do:
1) Set a specific width / height to the FrameLayout enclosing the ImageView and set android:scaleType to centerInside, fitCenter, or fitXY for the ImageViwe.
2) Programatically, in your activity, after onCreate, in onResume for example, you can get the LayoutParams and change the width and height of the ImageView doing you own scaleing. I take this aproach when I scale against the screen widht or height at run time.
EDIT 1
Example of second alternative:
public class TestActivity extends AppCompatActivity {
ImageView imgView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testactivity_layout);
imgView = (ImageView) findViewById(R.id.imgview);
}
#Override
protected void onResume() {
super.onResume();
ViewGroup.LayoutParams params = imgView.getLayoutParams();
params.width = 100;
}
}
Notes:
The width is expressed in pixel.
To get the display metrics:
How to get screen display metrics in application class
To establish a relative width for the ImageView, get the width of the display and calculate the desireed % as the width of the image.
Based on this answer to another question, a solution that removes the whitespace in the LinearLayout while preserving the height and aspect ratio of the image is:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
LinearLayout layout = (LinearLayout) findViewById(R.id.mLinearLayout);
ImageView imageView = (ImageView) findViewById(R.id.mImageView);
TextView textView = (TextView) findViewById(R.id.mTextView);
layout.getLayoutParams().width = textView.getWidth()+imageView.getWidth();
layout.requestLayout();
}
EDIT:
Based on #Juan's answer and these instructions, the following code also achieves the desired result:
#Override
protected void onResume() {
DisplayMetrics displayMetrics = new DisplayMetrics();
this.getWindowManager()
.getDefaultDisplay()
.getMetrics(displayMetrics);
ViewGroup.LayoutParams params = imgView.getLayoutParams();
params.height = (int)Math.floor(displayMetrics.heightPixels * 0.32);
}
I have a VideoView inside a xml which is inside a different xml
<main.xml
<include layout = "#layout/subLayou1"/> >
</main>
<subLayout1.xml
<include layout = "#layout/subLayout2"/> >
</subLayout1>
<subLayout2.xml
<VideoView
android:id="#+id/videoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:background="#android:color/transparent" />
<Button for full screen />
</subLayout2>
but i want this videoview in subLayout2 to take full-screen when a full screen button is clicked.. please help me out!!
In your code you have put the following width height for sublayout
android:layout_width="match_parent"
android:layout_height="match_parent"
Sublayout1 just includes sublayout2. You need to specify certain width and height other than wrap_content and match_parent.
Then in the java file for this activity:
VideoView vv = findViewById(R.id.videoView);
DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics);
android.widget.LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) videoView.getLayoutParams();
fullscreenbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
params.width = metrics.widthPixels;
params.height = metrics.heightPixels;
vv.setLayoutParams(params);
}
});
For setting the video back to original:
normalscreenbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
params.width = (int) (original_width_dp*metrics.density);
params.height = (int) (original_height_dp*metrics.density);
vv.setLayoutParams(params);
}
});
During fullscreen you find the value of the screensize and then set it to the videoview. On minimize you have to set the value back to the original. metrics.density converts dp into pixels.
Reference
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++);
A sprite on my android game is set to fall by 5 pixels every 100 milliseconds, this works fine the only problem is that the ImageView itself is only 53dp high, if I make it any bigger the image inside scales with it. Since the ImageView is only 53dp high the image disappears after 1100 milliseconds as it scrolls outside the boundaries of the imageview.
I need the layout height of the ImageView to fill_parent but I need the image to stay the same size instead of scaling with it, here's my current code:
<ImageView
android:id="#+id/blueman"
android:layout_width="0dip"
android:layout_height="53dp"
android:paddingRight="300dp"
android:layout_weight="0.03"
android:src="#drawable/fall" />
Thanks in advance :)
since you didn't give the full code of the layout, I'll make some assumptions...
you're talking about setting your sprite's height to the screen's height without scaling?
There should be a difference between your screen size (that is the root layout item) and the sprites in it. I guess you declared your layout as...:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?gameBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btTap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="14dp"
android:layout_marginTop="350dp"
android:background="#drawable/tap"
android:visibility="visible" />
<Button
android:id="#+id/btCellR1C1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="490dp"
android:layout_marginTop="155dp"
android:background="#drawable/cell_red" />
The only thing I had to cope with, was the scaling of my sprites depending on the device's resolution with such a method:
public static void scaleView(View view, int top, int left, int width,
int height) {
top = Math.round(top * scaleY);
left = Math.round(left * scaleX);
width = Math.round(width * scaleX);
height = Math.round(height * scaleY);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.height = height;
params.width = width;
params.topMargin = top;
params.leftMargin = left;
view.setLayoutParams(params);
view.setSoundEffectsEnabled(false);
}
Please give us more details to help you
Best regards
Serge
I want to resize my LinearLayout (or a view) to a dimension which is relative to the parent or itself. For example, I want the width to be 1/3 of the parent's width. Or, the height should be same as its own width. I don't want to use any constants , so that it works for all devices.
adding code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<LinearLayout android:id="#+id/ll_board"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
...
</LinearLayout>
code:
public class GMActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
LinearLayout board_layout = (LinearLayout)findViewById(R.id.ll_board);
// I wanted to resize board_layout here ..
// getParent().getWidth() returns 0
Log.d("gm", "layout: " + ((LinearLayout) board_layout.getParent()).getWidth());
// ..
}
}
getWidth() is giving 0. Is it too early to call this? If yes, what is the correct place to call this?
Basically my intention is to make the width of the layout a fraction of the screen size width, and, height same as its own width.
Considering layout your LinearLayout and that its parent it's another LinearLayout:
Get the parent's width:
int parentWidth = ((LinearLayout) layout.getParent()).getWidth();
Get the view's width:
int viewWidth = ((LinearLayout) layout).getWidth();
set the
view.setHeight(viewWidth );
view.setWidth(parentWidth / 3);
I found height=width solution (square shaped layout) in LinearLayout in Square Form