when I click on a RelativeLayout it change the size.
How can I make this change animated? So it looks like the rectangle grows to full screen?
My Layout:
<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"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#ff000000">
<RelativeLayout
android:id="#+id/srLayout"
android:layout_width="62.5dp"
android:layout_height="132.5dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="false"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:clickable="true"
android:onClick="sleepRoom"
android:background="#ffffffff"></RelativeLayout>
</RelativeLayout>
The code:
public void sleepRoom(View view) {
RelativeLayout sr = (RelativeLayout) findViewById(view.getId());
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) sr.getLayoutParams();
params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
sr.setLayoutParams(params);
}
Simple trick that worked for me:
Adding:
android:animateLayoutChanges="true"
to the xml of the view whose layoutParams you are changing.
Then, adding this line of code in your Java/Kotlin code before changing the params:
Java:
((ViewGroup) sr).getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
Kotlin:
(sr as ViewGroup).layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
To explicitly animate in this case, your sleepRoom() should look like this.
public void sleepRoom(View view) {
final RelativeLayout sr = (RelativeLayout) view;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) sr.getLayoutParams();
params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
sr.setLayoutParams(params);
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1);
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1);
PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 1);
PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1);
PropertyValuesHolder pvhRoundness = PropertyValuesHolder.ofFloat("roundness", 0, 1);
final Animator collapseExpandAnim = ObjectAnimator.ofPropertyValuesHolder(sr, pvhLeft, pvhTop,
pvhRight, pvhBottom, pvhRoundness);
collapseExpandAnim.setupStartValues();
sr.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
sr.getViewTreeObserver().removeOnPreDrawListener(this);
collapseExpandAnim.setupEndValues();
collapseExpandAnim.start();
return false;
}
});
}
However, normally android:animateLayoutChanges="true" should work.
For more specifics from the man Chet Haase, see: https://www.youtube.com/watch?v=55wLsaWpQ4g
because RelativeLayout extends View you can use all the animations you are using on "regular views". for example try using animate.scale() and see if it suits you. a simple way of doing it will be something like
#Override
protected void onCreate (Bundle savedInstanceState) {
sr = (RelativeLayout) findViewById(view.getId());
sv.setVisibility(View.GONE);
scaleEnd = sr.getScaleX();
sr.setScaleX(0);
}
...
#Override
protected void onPostCreate (Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
sr.setVisibility(View.Visible);
sr.animate.scaleX(scaleEnd);
}
Also if you want a Lollipop kind of animation have a look at: Use the Reveal Effect
Related
I am trying to implement auto-hiding feature for my toolbar using CoordinateLayout. But I also want to tweaks it a bit, so that the hide/show only works after I scroll past my imageview.
I am currently able to "turn on/off" the hide/show availability for the toolbar via AppBarLayout.LayoutParams. So right now it won't hide the toolbar if I scroll within the imageview's height and will hide if I scroll pass the imageview. The only problem is, if I scroll the layout very fast and instantly pull my finger before it pass the imageview's height the toolbar won't hide. In my opinion it is because the scrolling listener's function is called before the parameter of the toolbar's show/hide is changed to enable.
Here's the code:
ArticleActivity.java
public class ArticleActivity extends AppCompatActivity {
private Toolbar toolbar;
private ImageView imageView;
private NestedScrollView scrollView;
private Matrix matrix;
private int imageHeight = 0;
private float scale = 0;
private boolean hideable = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_article);
imageView = (ImageView) findViewById(R.id.imageView);
scrollView = (NestedScrollView) findViewById(R.id.scrollView);
toolbar = (Toolbar) findViewById(R.id.toolbar);
matrix = new Matrix();
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
scale = (float) displayMetrics.widthPixels / ((float) imageView.getDrawable().getIntrinsicWidth());
matrix.postScale(scale, scale);
imageView.setImageMatrix(matrix);
if(imageView.getViewTreeObserver().isAlive()) {
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
imageHeight = imageView.getHeight();
}
});
}
if(scrollView.getViewTreeObserver().isAlive()) {
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
int scrollY = scrollView.getScrollY();
if(scrollY <= imageHeight) {
matrix.setTranslate(0, scrollY / 4);
matrix.postScale(scale, scale);
imageView.setImageMatrix(matrix);
if(hideable) {
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
params.setScrollFlags(0);
toolbar.setLayoutParams(params);
hideable = false;
}
} else {
if(!hideable) {
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
// 1 = scroll, 4 = enterAlways, 16 = snap
params.setScrollFlags(21);
toolbar.setLayoutParams(params);
hideable = true;
}
}
}
});
}
}}
activity_article.xml:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="matrix"
android:src="#drawable/download"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/imageView"
android:text="What is Lorem Ipsum?"/>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
What should I do to fix this? Or is there another way to achieve this? Thank you
To drag the Image on the screen I created my own class:
private class CustomImageView extends AppCompatImageView
In the constructor I want to set params:
public CustomImageView(Context context) {
super(context);
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
params.bottomMargin = 50;
this.setScaleType(ImageView.ScaleType.CENTER_CROP);
this.setLayoutParams(params);
this.setWillNotDraw(false);
}
my activity_main.xml:
<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="com.example.eleizo.firstapplication.MainActivity">
</RelativeLayout>
I want to have actually as it would be :
<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="com.example.eleizo.firstapplication.MainActivity">
<ImageView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:layout_marginBottom="50dp"
/>
</RelativeLayout>
Why string "params.bottomMargin = 50" doesn't work? I tried to set params = new RelativeLayout.LayoutParams(val1,val2) but it's no matter.
How set android:layout_marginBottom in RelativeLayout by code?
try using the LayoutParams while you are adding the view in the relative layout. ViewGroup.addView(View, LayoutParams) .
Something like this.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
params.bottomMargin = 50;
relativeLayout.addView(new CutomImageView(context), params);
Try using MarginLayoutParams instead of LayoutParams.
if( params instanceof MarginLayoutParams )
{
((MarginLayoutParams) params).bottomMargin = 50;
((MarginLayoutParams) params).leftMargin = 10;
}
So your code would look like
public CustomImageView(Context context) {
super(context);
params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
if( params instanceof MarginLayoutParams )
{
((MarginLayoutParams) params).bottomMargin = 50;
}
this.setScaleType(ImageView.ScaleType.CENTER_CROP);
this.setLayoutParams(params);
this.setWillNotDraw(false);
}
With the following Java and XML code, I was wondering how to retrieve the dimensions in pixels of an inner/child layout (LinearLayout, whereas the parent is RelativeLayout with paddings of 20dp) properly:
Java code:
public class TestActivity extends Activity {
private LinearLayout linLay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
linLay = (LinearLayout)findViewById(R.id.linLay);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
linLay.setLayoutParams(lp);
getDimensions();
}
private void getDimensions() {
System.out.println(linLay.getHeight());
System.out.println(linLay.getWidth());
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp" >
<LinearLayout
android:id="#+id/linLay"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true">
</LinearLayout>
</RelativeLayout>
... Since I get outputs of 0 for the dimensions, I am aware that the LinearLayout needs to be set first on the screen before I could retrieve the dimensions... But what am I doing wrong here?
It didn't get its dimensions at the time you try to output them.You can just add a delay or just use method below.
private void getDimensions() {
ViewTreeObserver vto = linLay.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
#Override
public voidonGlobalLayout() {
linLay.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height =linLay.getMeasuredHeight();
int width =linLay.getMeasuredWidth();
System.out.println(height);
System.out.println(width);
}
});
}
First, I know this is a duplicate of other question but I couldn't manage to fix it so I created my own question for help. I am trying to get the RelativeLayout width, it was successful at first but I don't know what I changed and the code returns only zero.
Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView[] imageViewArray = new ImageView[20];
ArrayList<Float> xarray = new ArrayList<>();
ArrayList<Float> yarray = new ArrayList<>();
rlt = (RelativeLayout) findViewById(R.id.layout);
imageView = (ImageView) findViewById(R.id.imageView);
rlt.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
rlt.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Toast.makeText(MainActivity.this, "right" + rlt.getWidth(), Toast.LENGTH_SHORT).
show();
layoutwidth = rlt.getWidth();
layoutheight = rlt.getHeight();
}
});
}
Here is my activity_main xml file:
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:id="#+id/layout"
android:background="#android:color/black"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:src="#mipmap/you"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
Simple one, but yet not working, any help please?
It's because your layout's width isn't set yet
You should override onLayout() method
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
height = bottom - top;
width = right - left;
}
Usually you would extend whatever View you're interested in (here RelativeLayout) and override onSizeChanged():
https://developer.android.com/reference/android/view/View.html#onSizeChanged(int,%20int,%20int,%20int)
Whether that is useful in your scenario or not is hard to tell, since your question is fairly generic.
Try
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run()
{
//get width here
}
}, 10);
Maybe try to put the code for the views into the "onPostCreate" Method
There has been many questions on dynamically setting the position of a button, but I just want to change the position of a button into center of the screen. My layout is RelativeLayout.
Updated:
At the beginning, myButton has been set position in XML as:
<Button
android:id="#+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Menu" />
Any suggestion would be greatly appreciated
See an example below (click the button and it will be moved to the center).
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/my_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Menu" />
</RelativeLayout>
MainActivity.java:
public class MainActivity extends Activity {
private View mView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mView = findViewById(R.id.my_view);
mView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ViewGroup.LayoutParams vg_lp = mView.getLayoutParams();
// Make sure we are in RelativeLayout
if (vg_lp instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams rl_lp = new RelativeLayout.LayoutParams(vg_lp);
rl_lp.addRule(RelativeLayout.CENTER_IN_PARENT);
mView.setLayoutParams(rl_lp);
}
}
});
}
}
Try:
......
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) button.getLayoutParams();
layoutParams.leftMargin = parentLayout.getWidth()/2;
layoutParams.topMargin = parentLayout.getHeight()/2;
button.setLayoutParams(layoutParams);
......
Try this one:
RelativeLayout RL = (RelativeLayout)findViewById(R.id.relative_layout);
RL.gravity(Gravity.CENTER);
with this all subviews of RL will be in center;
Button anyButton = new Button(this);
RL.addSubview(anyButton);//this genereted button will be in center as well
Try this,
RelativeLayout my_layout = new RelativeLayout(this);
my_layout.setId(some_value);
Button my_btn = new Button(this);
RelativeLayout.LayoutParams my_params = new RelativeLayout.LayoutParams(btn_height,btn_width);
my_params.addRule(RelativeLayout.CENTER_IN_PARENT,my_layout.getId());
my_layout.addView(my_btn,my_params);
Add this 2 lines to the component you want to center in the xml file :
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"