I've an image (image1.png)
When I click on some button, I want this image to be displayed in the middle of the screen for a second and disappear. How can I do it?
I guess that it brings me the center coordinates of the screen.
public void onClick(View button) {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics( dm );
int screenMiddlePointWidth = dm.widthPixels / 2;
int screenMiddlePointHeight = dm.heightPixels / 2;
}
p.s. I don't want the image to push other views on the screen so I can't set it as invisible\gone
Hi use this code in xml to place your image in center
<?xml version="1.0" encoding="utf-8"?>
<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="com.myapplication.MainActivity"
tools:showIn="#layout/activity_main">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/image1"
android:layout_centerInParent="true"/>
</RelativeLayout>
and then in java file use the following code
ImageView img;
img=(ImageView)findViewById(R.id.imgview);
CountDownTimer timer = new CountDownTimer(1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
img.setVisibility(View.GONE);
}
};
timer.start();
you can use the timer code in onCreate method or anywhere you want.
If you want to center your image programatically use the following code.
image.setBackgroundResource(R.drawable.image1);
LayoutParams params = (LayoutParams) image.getLayoutParams();
params.gravity = Gravity.CENTER;
img.setLayoutParams(params);
Related
I have a fragment that displays some images on 30% of the screen. In case when image.height is bigger than image.width, I wanted to rotate the image 90 degrees. However, after that operation, the image does not fully fill the fragment - "new" width after rotation matches previous height, so the image occupies only some part in the middle of the fragment. How can I make it a matching fragment? What I'm doing wrong or missing?
This is how it looks like without rotation:
This is after rotation:
And that's what I want to have:
Here is the code:
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setImageFittedToDisplay(view);
}
public void setImageFittedToDisplay(View view) {
int height = getDisplayMetrics().heightPixels;
ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = ((Double) (height * 0.3)).intValue();
view.setLayoutParams(params);
ImageView image = view.findViewById(R.id.picture);
image.setDrawingCacheEnabled(true);
int w = image.getDrawable().getIntrinsicWidth();
int h = image.getDrawable().getIntrinsicHeight();
if(h > w) {
image.setRotation(90f);
}
ViewGroup.LayoutParams imageParams = image.getLayoutParams();
imageParams.height = ActionBar.LayoutParams.WRAP_CONTENT;
imageParams.width = ActionBar.LayoutParams.WRAP_CONTENT;
image.setLayoutParams(imageParams);
}
and here is .xml of the fragment:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/APOD_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="#+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/cool_pic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/separator"
android:layout_width="match_parent"
android:layout_height="10dp"
android:background="#color/colorSeparator"
app:layout_constraintBottom_toBottomOf="#+id/picture"
app:layout_constraintTop_toBottomOf="#+id/picture" />
</androidx.constraintlayout.widget.ConstraintLayout>
I am developing an Android application where an activity displays content in a scrollview. At the top of the content there is a placeholder for an image to be displayed. The image is downloaded from the Internet and may take a few seconds until it is ready to be displayed. The image placeholder is initially empty. When the image is downloaded, it is dynamically added to the placeholder.
Initially I had the following problem.
The user starts the activity and scrolls down
The image starts to download in the background. When available, it is added to the placeholder
When the image is added to the placeholder, the contents of the scrollview change and the user experience is disrupted by the unwanted scrolling that occurs
To fix this, I added code to adjust the scroll position once the image view is added to the placeholder. The problem with this is that a flickering is caused on the scrollview during the display-image and adjust-scrollview process. The reason is that the scrollBy function is called from a runnable. Calling scrollBy outside the runnable does not cause flickering but the scroll position is incorrect - the reason for this is that there is not enough time for the items on the scroll view to recalculate/measure their dimensions/heights.
Here is a sample application the illustrates this problem:
public class MainActivity extends AppCompatActivity {
ScrollView scrollView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = findViewById(R.id.scrollview);
startImageDownload();
simulateImageScroll();
}
private void simulateImageScroll() {
// scroll to the bottom of the scroll view
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
}
});
}
private void startImageDownload() {
Handler handler = new Handler(getMainLooper());
// simulate a delay for the image download to illustrate the flashing problem in the scrollview
handler.postDelayed(new Runnable() {
#Override
public void run() {
displayImage("");
}
}, 2000);
}
// when the image is downloaded we add it to the image container
private void displayImage(String imageFilename) {
// dynamically create an image and add it to the image container layout
RelativeLayout container = findViewById(R.id.imageContainer);
ImageView img = new ImageView(this);
// image should be loaded from the given filename - for now use a solid background and fixed height
img.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, 500);
container.addView(img, params);
adjustScrolling(container);
}
private void adjustScrolling(RelativeLayout container) {
// adjust scroll if the image is loaded before the current content
if (scrollView.getScrollY() > container.getTop()) {
container.measure(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
final int amountToScroll = container.getMeasuredHeight();
// the following does not cause flickering but scrolls to the wrong position
//scrollView.scrollBy(0, amountToScroll);
// adjust the scrollview so that it keeps the current view unchanged
scrollView.post(new Runnable() {
#Override
public void run() {
// this causes flickering but scrolls to the correct position
scrollView.scrollBy(0, amountToScroll);
}
});
}
}
}
And here is the layout file:
<ScrollView
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/imageContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:background="#aa0000" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="4"
android:textColor="#ffffff"
android:textSize="128dp"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
Any ideas on how to fix this problem?
Edited:
Currently, your layout is flickering, because adding blue view cause redraw layout (and scroll). So scroll occurred once, and next you scrolled to the position you want. That's the second moving.
To solve this problem, you need to know how android draws view.
https://developer.android.com/guide/topics/ui/how-android-draws.html
Simply, onMeasure() - onLayout() - onDraw(). And you can add your layout code between onLayout() and onDraw(), by ViewTreeObserver().addOnGlobalLayoutListener().
https://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html
ps: I still recommend using nice and lovely image library, Picasso.
Fixed code is: Set scroll before draw() called. By this, you can draw only once.
public class MainActivity extends AppCompatActivity {
ScrollView scrollView;
int amountToScroll = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = findViewById(R.id.scrollview);
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
scrollView.scrollBy(0, amountToScroll);
amountToScroll = 0;
}
});
startImageDownload();
simulateImageScroll();
}
private void simulateImageScroll() {
// scroll to the bottom of the scroll view
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, scrollView.getMaxScrollAmount());
}
});
}
private void startImageDownload() {
Handler handler = new Handler(getMainLooper());
// simulate a delay for the image download to illustrate the flashing problem in the scrollview
handler.postDelayed(new Runnable() {
#Override
public void run() {
displayImage("");
}
}, 2000);
}
// when the image is downloaded we add it to the image container
private void displayImage(String imageFilename) {
// dynamically create an image and add it to the image container layout
RelativeLayout container = findViewById(R.id.imageContainer);
ImageView img = new ImageView(this);
// image should be loaded from the given filename - for now use a solid background and fixed height
img.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, 500);
container.addView(img, params);
adjustScrolling(container);
}
private void adjustScrolling(RelativeLayout container) {
// adjust scroll if the image is loaded before the current content
if (scrollView.getScrollY() > container.getTop()) {
container.measure(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
amountToScroll = container.getMeasuredHeight();
}
}
}
I strongly recommend using Picasso. http://square.github.io/picasso/
This one line will fix all of your problem.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
You can load your local image file or network image (url) into your imageView.
In your case, remove both startImageDownload() and simulateImageScroll(), and on onResume(), call displayImage().
Fixed displayImage():
private void displayImage(String imageFilename) {
// dynamically create an image and add it to the image container layout
RelativeLayout container = findViewById(R.id.imageContainer);
ImageView img = new ImageView(this);
// image should be loaded from the given filename - for now use a solid background and fixed height
img.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, 500);
container.addView(img, params);
Picasso.with(this).load(imageFilename).into(img);
adjustScrolling(container);
}
Or, if you want to solve this problem directly for academic reasons,
Do not adjust your scroll. It seems that it is not a real solution to use scrollBy to fix your problem. The real cause is the code that cause the UI to redraw. May be calling invalidate() or something like that.
Adding ImageView programmatically is not a good idea. Because your RecyclerView or ViewHolder of ListView cannot reuse the view, so it cause degrade performance. If you can avoid it, do that. (eg. use xml)
It seems that adding your ImageView to imageContainer is real problem. imageContainer has android:layout_height="wrap_content" property, and this means it has no fixed height, it depends on it's own child. Try to change to fixed value, for example: android:layout_height="500dp"
Well first if it's a single image on top then you don't have to create imageview dynamically just use it inside your XML file without Relative-layout. set to an default image. Use Image-View with adjustViewBounds="true" and scaleType="fitCenter" then you don't have to worry about the image scaling.
<ImageView
android:id="#id/img"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
you can use Picasso http://square.github.io/picasso/ library as suggested by "Stanley Kou" for loading the image.
My Suggestion is to use Progress Bar, Start the Progress bar when image starts downloading and hide it once the image load is complete then let the user see the activity.
<ProgressBar
android:id="#+id/indeterminateBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
For more details, please check -
https://developer.android.com/reference/android/widget/ProgressBar.html
I have researched this on Stack Overflow, but I didn't find the fix to my problem. I have a view that contains the code for a vertical, yellow line on the screen. I have an activity that creates the dialog whose content view is an instance of the view. The dialog pops up, but the yellow line doesn't show. What am I missing? Here is my code:
View :
public guidelines(Context context) {
super(context);
int x = this.getWidth()/2 - 3;
int y = this.getHeight();
shape = new ShapeDrawable(new RectShape());
shape.getPaint().setColor(Color.YELLOW);
shape.setBounds(x, 0, x+6, y);
}
#Override
protected void onDraw(Canvas canvas) {
shape.draw(canvas);
}
Layout for the View :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/---
android:layout_width="match_parent" android:layout_height="match_parent">
<!-- <--- android:background="#ccc"
android:layout_width="300dp" android:layout_height="300dp" android:paddingLeft="20dp"
android:paddingBottom="40dp" app:exampleDimension="24sp" app:exampleColor="#33b5e5"
app:exampleString="Hello, guidelines" /> -->
< ---
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/frame"/>
</FrameLayout>
Dialog Calling Code :
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
guidelines g = new guidelines(this);
dialog.setContentView(g);
dialog.show();
Thanks.
It was better to just use the drawRect function of the canvas. I did that and it worked.
I am building an application which display a map (the map is the canvas background) and localise users by adding circle on the canvas(using draw circle). I would like to add a button over the canvas(for now a draw a button on the map and check with ontouch() if the user clicked on it) and when the button is touched I would like to have a window popup. It worked but the popup is behind the canvas(I could see a small piece of it(I removed it)).Is there a way to have my canvas BEHIND the button and the popup window? I saw people talking about putting the canvas in relative layout but I have no idea how to do that.
Here is the xml of my activity, really simple:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/umap2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Button" />
</RelativeLayout>
And here is my activity java code(I removed a couple of things that doesnt have nothing to do with my problem)
package com.example.client;
import java.util.LinkedList;
//....
import java.util.Timer;
public class Campus extends Activity{
final Handler myHandler = new Handler();
MapView mapv;
final Activity self = this;
Float ratioX;
Float ratioY;
int width;
int height;
static boolean out=false;
Intent i;
//creating a linked list for each hall
static LinkedList<compMac> DMS = new LinkedList<compMac>();
static LinkedList<compMac> MCD = new LinkedList<compMac>();
//...
static LinkedList<compMac> SCI = new LinkedList<compMac>();
static LinkedList<compMac> STE = new LinkedList<compMac>();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.campus);
setSize();
this.mapv = new MapView(this);//!! my view
setContentView(mapv);
i= new Intent(this, myService.class);
this.startService(i);
}
//*******************************View class!*******************************
public class MapView extends View {
/*
* Extract the connected users and location from the array. separate the
* array into an array for each building
* */
private Paint redPaint;
private float radius;
Canvas canvas;
public MapView(Context context) {
super(context) ;
redPaint = new Paint();
redPaint.setAntiAlias(true);
redPaint.setColor(Color.RED);
redPaint.setTextSize(10);
}
#Override
//drawing a point on every hall on the map where users are connected
public void onDraw (Canvas canvas) {
// draw your circle on the canvas
if(!out)
{
AlertDialog.Builder outOfCampus = new AlertDialog.Builder(self);
outOfCampus.setTitle("Sorry");
outOfCampus.setMessage("You are out of Campus");//(toDisplay);
outOfCampus.setCancelable(false);
outOfCampus.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
startActivity(new Intent("com.example.client.Sin"));
}});
AlertDialog alertdialog = outOfCampus.create();
outOfCampus.show();
}
this.canvas=canvas;
setBackgroundResource(R.drawable.umap2);
}
public void drawPoints(LinkedList<compMac> building)
{
if(!building.isEmpty())
{
while(!building.isEmpty())
{
compMac current = building.pop();
Float x= ratioX*(Float.parseFloat(current.getCoorX()));
Float y= ratioY*(Float.parseFloat(current.getCoorY()));
// Log.w("ratioX ",(((Double)(width/768)).toString()));
// Log.w("ratioY ",(float)(y.toString()));
canvas.drawCircle (x,y, 10, redPaint);
}
}
}
public boolean onTouchEvent (MotionEvent event) {
//...//
return true;
}
}
}
Someone have an idea how i can do that? Thanks
Calling setContentView two times would not work. Instead you should put your canvas view and the button in a single layout itself but with proper ordering. The last widget in the relative layout gets more priority, so if you want the button to come on top of the canvas your layout should be something like this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/umap2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.client.MapView
android:id="#+id/mapView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Button" />
</RelativeLayout>
And to access your MapView in java class
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.campus);
setSize();
this.mapv = findViewById(R.id.mapView); //!! my view
i= new Intent(this, myService.class);
this.startService(i);
}
And obviously alert dialog will be on top of the canvas. Hope it helps!
Edit: I think inflate error is due to incorrect class path. Since MapView is inner class of Campus, path should be like this
<com.example.client.Campus.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Also add this constructor to your MapView class
public MapView(Context context, AttributeSet attributeSet) {
super(context, attributeSet) ;
redPaint = new Paint();
redPaint.setAntiAlias(true);
redPaint.setColor(Color.RED);
redPaint.setTextSize(10);
}
<FrameLayout 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 xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/umap2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/btn_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#drawable/back_transparent_pressed" >
<Button
android:id="#+id/button1"
android:layout_centerInParent="true"
/>
</RelativeLayout>
I have designed a simple layout.I have finished the design without animation, but now I want to add animations when textview click event and I don't know how to use it.
Did my xml design looks good or not?
Any suggestions would be appreciated.
My XML
<?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:longClickable="false"
android:orientation="vertical"
android:weightSum="16" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#00DDA0"
android:layout_weight="3" >
</LinearLayout>
<TextView
android:id="#+id/Information1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:text="Child Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="8.5"
android:background="#BBBBBB"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Parent Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout2"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Siblings"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout3"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information4"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Teacher Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout4"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information5"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Grade Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout5"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</LinearLayout>
<TextView
android:id="#+id/Information6"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="Health Information"
android:background="#0390BE"
android:layout_weight="0.75"
android:textColor="#FFFFFF"
android:layout_gravity="center|fill_horizontal"/>
<LinearLayout
android:id="#+id/layout6"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#BBBBBB"
android:layout_weight="8.5" >
<TextView
android:id="#+id/textView5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView"
android:layout_weight="8.5" />
</LinearLayout>
</LinearLayout>
My java
public class Certify_Info extends Activity {
private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
private static LinearLayout l1,l2,l3,l4,l5,l6;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_certify__info);
tv1=(TextView) findViewById(R.id.Information1);
tv2=(TextView) findViewById(R.id.Information2);
tv3=(TextView) findViewById(R.id.Information3);
tv4=(TextView) findViewById(R.id.Information4);
tv5=(TextView) findViewById(R.id.Information5);
tv6=(TextView) findViewById(R.id.Information6);
l1=(LinearLayout) findViewById(R.id.layout1);
l2=(LinearLayout) findViewById(R.id.layout2);
l3=(LinearLayout) findViewById(R.id.layout3);
l4=(LinearLayout) findViewById(R.id.layout4);
l5=(LinearLayout) findViewById(R.id.layout5);
l6=(LinearLayout) findViewById(R.id.layout6);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
tv1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l1.setVisibility(View.VISIBLE);
}
});
tv2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l2.setVisibility(View.VISIBLE);
}
});
tv3.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l3.setVisibility(View.VISIBLE);
}
});
tv4.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l4.setVisibility(View.VISIBLE);
}
});
tv5.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l6.setVisibility(View.GONE);
l5.setVisibility(View.VISIBLE);
}
});
tv6.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setVisibility(View.GONE);
l2.setVisibility(View.GONE);
l3.setVisibility(View.GONE);
l4.setVisibility(View.GONE);
l5.setVisibility(View.GONE);
l6.setVisibility(View.VISIBLE);
}
});
}
}
You can do two things to add animations, first you can let android animate layout changes for you. That way every time you change something in the layout like changing view visibility or view positions android will automatically create fade/transition animations. To use that set
android:animateLayoutChanges="true"
on the root node in your layout.
Your second option would be to manually add animations. For this I suggest you use the new animation API introduced in Android 3.0 (Honeycomb). I can give you a few examples:
This fades out a View:
view.animate().alpha(0.0f);
This fades it back in:
view.animate().alpha(1.0f);
This moves a View down by its height:
view.animate().translationY(view.getHeight());
This returns the View to its starting position after it has been moved somewhere else:
view.animate().translationY(0);
You can also use setDuration() to set the duration of the animation. For example this fades out a View over a period of 2 seconds:
view.animate().alpha(0.0f).setDuration(2000);
And you can combine as many animations as you like, for example this fades out a View and moves it down at the same time over a period of 0.3 seconds:
view.animate()
.translationY(view.getHeight())
.alpha(0.0f)
.setDuration(300);
And you can also assign a listener to the animation and react to all kinds of events. Like when the animation starts, when it ends or repeats etc. By using the abstract class AnimatorListenerAdapter you don't have to implement all callbacks of AnimatorListener at once but only those you need. This makes the code more readable. For example the following code fades out a View moves it down by its height over a period of 0.3 seconds (300 milliseconds) and when the animation is done its visibility is set to View.GONE.
view.animate()
.translationY(view.getHeight())
.alpha(0.0f)
.setDuration(300)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});
The easiest way to animate Visibility changes is use Transition API which available in support (androidx) package. Just call TransitionManager.beginDelayedTransition method then change visibility of the view. There are several default transitions like Fade, Slide.
import androidx.transition.TransitionManager;
import androidx.transition.Transition;
import androidx.transition.Fade;
private void toggle() {
Transition transition = new Fade();
transition.setDuration(600);
transition.addTarget(R.id.image);
TransitionManager.beginDelayedTransition(parent, transition);
image.setVisibility(show ? View.VISIBLE : View.GONE);
}
Where parent is parent ViewGroup of animated view. Result:
Here is result with Slide transition:
import androidx.transition.Slide;
Transition transition = new Slide(Gravity.BOTTOM);
It is easy to write custom transition if you need something different. Here is example with CircularRevealTransition which I wrote in another answer. It shows and hide view with CircularReveal animation.
Transition transition = new CircularRevealTransition();
android:animateLayoutChanges="true" option does same thing, it just uses AutoTransition as transition.
Try adding this line to the xml parent layout
android:animateLayoutChanges="true"
Your layout will look like this
<?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:animateLayoutChanges="true"
android:longClickable="false"
android:orientation="vertical"
android:weightSum="16">
.......other code here
</LinearLayout>
Please check this link. Which will allow animations like L2R, R2L, T2B, B2T animations.
This code shows animation from left to right
TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);
if you want to do it from R2L then use
TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);
for top to bottom as
TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());
and vice a versa..
Base on #ashakirov answer, here is my extension to show/hide view with fade animation
fun View.fadeVisibility(visibility: Int, duration: Long = 400) {
val transition: Transition = Fade()
transition.duration = duration
transition.addTarget(this)
TransitionManager.beginDelayedTransition(this.parent as ViewGroup, transition)
this.visibility = visibility
}
Example using
view.fadeVisibility(View.VISIBLE)
view.fadeVisibility(View.GONE, 2000)
I was able to show/hide a menu this way:
MenuView.java (extends FrameLayout)
private final int ANIMATION_DURATION = 500;
public void showMenu()
{
setVisibility(View.VISIBLE);
animate()
.alpha(1f)
.setDuration(ANIMATION_DURATION)
.setListener(null);
}
private void hideMenu()
{
animate()
.alpha(0f)
.setDuration(ANIMATION_DURATION)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
setVisibility(View.GONE);
}
});
}
Source
Based on the answer of #Xaver Kapeller I figured out a way to create scroll animation when new views appear on the screen (and also animation to hide them).
It goes from this state:
Button
Last Button
to
Button
Button 1
Button 2
Button 3
Button 4
Last Button
and viceversa.
So, when the user clicks on the first button, the elements "Button 1", "Button 2", "Button 3" and "Button 4" will appear using fade animation and the element "Last Button" will move down till end. The height of the layout will change as well, allowing using scroll view properly.
This is the code to show elements with animation:
private void showElements() {
// Precondition
if (areElementsVisible()) {
Log.w(TAG, "The view is already visible. Nothing to do here");
return;
}
// Animate the hidden linear layout as visible and set
// the alpha as 0.0. Otherwise the animation won't be shown
mHiddenLinearLayout.setVisibility(View.VISIBLE);
mHiddenLinearLayout.setAlpha(0.0f);
mHiddenLinearLayout
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.alpha(1.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
updateShowElementsButton();
mHiddenLinearLayout.animate().setListener(null);
}
})
;
mLastButton
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.translationY(mHiddenLinearLayoutHeight);
// Update the high of all the elements relativeLayout
LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();
// TODO: Add vertical margins
layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
}
and this is the code to hide elements of the animation:
private void hideElements() {
// Precondition
if (!areElementsVisible()) {
Log.w(TAG, "The view is already non-visible. Nothing to do here");
return;
}
// Animate the hidden linear layout as visible and set
mHiddenLinearLayout
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
Log.v(TAG, "Animation ended. Set the view as gone");
super.onAnimationEnd(animation);
mHiddenLinearLayout.setVisibility(View.GONE);
// Hack: Remove the listener. So it won't be executed when
// any other animation on this view is executed
mHiddenLinearLayout.animate().setListener(null);
updateShowElementsButton();
}
})
;
mLastButton
.animate()
.setDuration(ANIMATION_TRANSITION_TIME)
.translationY(0);
// Update the high of all the elements relativeLayout
LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();
// TODO: Add vertical margins
layoutParams.height = mLastButton.getHeight();
}
Note there is a simple hack on the method to hide the animation. On the animation listener mHiddenLinearLayout, I had to remove the listener itself by using:
mHiddenLinearLayout.animate().setListener(null);
This is because once an animation listener is attached to an view, the next time when any animation is executed in this view, the listener will be executed as well. This might be a bug in the animation listener.
The source code of the project is on GitHub:
https://github.com/jiahaoliuliu/ViewsAnimated
Happy coding!
Update: For any listener attached to the views, it should be removed after the animation ends. This is done by using
view.animate().setListener(null);
My solution extension
fun View.slideVisibility(visibility: Boolean, durationTime: Long = 300) {
val transition = Slide(Gravity.BOTTOM)
transition.apply {
duration = durationTime
addTarget(this#slideVisibility)
}
TransitionManager.beginDelayedTransition(this.parent as ViewGroup, transition)
this.isVisible = visibility
}
Use:
textView.slideVisibility(true)
Find the below code to make visible the view in Circuler reveal, if you send true, it'll get Invisible/Gone. If you send false, it'll get visible. anyView is the view you're going to visible/hide, it could be any view (Layouts, Buttons etc)
private fun toggle(flag: Boolean, anyView: View) {
if (flag) {
val cx = anyView.width / 2
val cy = anyView.height / 2
val initialRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
val anim = ViewAnimationUtils.createCircularReveal(anyView, cx, cy, initialRadius, 0f)
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
anyView.visibility = View.INVISIBLE
}
})
anim.start()
} else {
val cx = anyView.width / 2
val cy = anyView.height / 2
val finalRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
val anim = ViewAnimationUtils.createCircularReveal(anyView, cx, cy, 0f, finalRadius)
anyView.visibility = View.VISIBLE
anim.start()
}
}