Explicit animations for setAnimationStyle(), what are my choices? - java

I would like to try out different animation styles for a popup window using setAnimationStyle(), but I am struggling to understand the documentation.
developer.android.com, says: "animation style to use when the popup appears and disappears. Set to -1 for the default animation, 0 for no animation, or a resource identifier for an explicit animation."
It does not give any examples, or tell me what choices of resource are available. I suspect the best animation for my purposes will be sliding in from the right... does that exist as an option? Are these things I can select from a list or do I have to somehow create my own?
EDIT: My current code for making my popup window is something like this (simplified):
public void completed_dialog()
{
runOnUiThread(new Runnable()
{
public void run()
{
View layout = inflater.inflate(R.layout.endofgame, null, false);
Button b1 = (Button) layout.findViewById(R.id.pu_menu);
Button b2 = (Button) layout.findViewById(R.id.pu_repeat);
Button b3 = (Button) layout.findViewById(R.id.pu_next);
b1.setBackgroundResource(R.drawable.custom_menu_but);
b2.setBackgroundResource(R.drawable.custom_repeat_but);
b3.setBackgroundResource(R.drawable.custom_next_but);
b1.setOnClickListener(menu_button_click_listener);
b2.setOnClickListener(repeat_button_click_listener);
b3.setOnClickListener(next_button_click_listener);
final PopupWindow pw = new PopupWindow(layout, canvas_width,
canvas_width /2, true);
pw.setAnimationStyle(android.R.style.Animation_Dialog);
pw.showAtLocation(game_frame_layout, Gravity.CENTER, 0, 0);
}
}
}
I have now put the following in a file res/anim/test.xml :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.3" android:toXScale="1.0"
android:fromYScale="0.3" android:toYScale="1.0"
android:pivotX="0%" android:pivotY="0%"
android:duration="#android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="#android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="#android:integer/config_shortAnimTime"
/>
</set>
The original code with pw.setAnimationStyle(android.R.style.Animation_Dialog); worked fine, in as much as the dialog appeared with the standard animation - but if I swapped that line with pw.setAnimationStyle(R.anim.test); there is no animation. I have no idea why.

this is working example of setAnimationStyle() on my end:
res/anim/in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator">
<translate
android:fromYDelta="854"
android:toYDelta="0"
android:duration="1000"/>
</set>
res/anim/out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:interpolator="#android:anim/decelerate_interpolator"
android:fromYDelta="0"
android:toYDelta="854"
android:duration="10000"
/>
</set>
layout/main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/layout"
>
<Button
android:id="#+id/btn_show"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="show"
/>
</RelativeLayout >
layout/popup.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#cccccc"
>
<Button
android:id="#+id/btn_dismiss"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="dismiss"/>
</LinearLayout>
values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="PopupAnimation" parent="android:Animation" mce_bogus="1">
<item name="android:windowEnterAnimation">#anim/in</item>
<item name="android:windowExitAnimation">#anim/out</item>
</style>
</resources>
values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">Popupwindow</string>
</resources>
MainActivity.java :
public class MainActivity extends Activity {
/** Called when the activity is first created. */
boolean flag =false;
PopupWindow popupWindow;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
public void init() {
Button btn_show = (Button) findViewById(R.id.btn_show);
LayoutInflater inflater = LayoutInflater.from(this);
View layout = inflater.inflate(R.layout.popup, null);
popupWindow =new PopupWindow(layout, LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
Button btn_dismiss = (Button) layout.findViewById(R.id.btn_dismiss);
btn_dismiss.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
openMenu();
}
});
btn_show.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
openMenu();
}
});
}
public void btn_showOnClicked() {
openMenu();
}
public void btn_dismissOnClicked() {
openMenu();
}
public void openMenu() {
if (!flag) {
popupWindow.setAnimationStyle(R.style.PopupAnimation);
popupWindow.showAtLocation(findViewById(R.id.btn_show), Gravity.NO_GRAVITY, 0, 0);
popupWindow.setFocusable(true);
popupWindow.update();
flag =true;
} else {
popupWindow.dismiss();
popupWindow.setFocusable(false);
flag =false;
}
}
}
and in your code just add your anim file to style as:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="test" parent="android:Animation" mce_bogus="1">
<item name="android:windowEnterAnimation">#anim/test</item>
</style>
</resources>
and in code:
pw.setAnimationStyle(android.R.style.test);
Thanks & Happy Coding!!!

You can see the options in the documentation of R.style. But there aren't many though. If you want more than that you will need to create it yourself. See basic guide here.
A few more examples of custom made animations you may find at the simple-quickactions google code site.
As per your comment, I think you should specify the id of your style as R.style.Animation_test.

Related

A circular status of a countdown timmer [duplicate]

I am trying to create a rounded progressbar. This is what I want to achieve
There is a grey color background ring. On top of it, a blue color progressbar appears which moves in a circular path from 0 to 360 in 60 or whatever amount of seconds.
Here is my example code.
<ProgressBar
android:id="#+id/ProgressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?android:attr/progressBarStyleLarge"
android:indeterminateDrawable="#drawable/progressBarBG"
android:progress="50"
/>
To do this, in the drawable "progressBarBG", I am creating a layerlist and inside that layer list I am giving two items as shown.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape
android:shape="ring"
android:innerRadius="64dp"
android:thickness="8dp"
android:useLevel="false">
<solid android:color="#color/grey" />
</shape>
</item>
<item android:id="#android:id/progress">
<clip>
<shape
android:shape="ring"
android:innerRadius="64dp"
android:thickness="8dp"
android:useLevel="false">
<solid android:color="#color/blue" />
</shape>
</clip>
</item>
Now, the first grey ring is generated fine. The blue ring however starts from the left of the drawable and goes to the right just like how a linear progressbar works. This is how it shows at 50% progress with the red color arrow showing direction.
I want to move the blue progressbar in circular path as expected.
Here are my two solutions.
Short answer:
Instead of creating a layer-list, I separated it into two files. One for ProgressBar and one for its background.
This is the ProgressDrawable file (#drawable folder): circular_progress_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="270"
android:toDegrees="270">
<shape
android:innerRadiusRatio="2.5"
android:shape="ring"
android:thickness="1dp"
android:useLevel="true"><!-- this line fixes the issue for lollipop api 21 -->
<gradient
android:angle="0"
android:endColor="#007DD6"
android:startColor="#007DD6"
android:type="sweep"
android:useLevel="false" />
</shape>
</rotate>
And this is for its background(#drawable folder): circle_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:innerRadiusRatio="2.5"
android:thickness="1dp"
android:useLevel="false">
<solid android:color="#CCC" />
</shape>
And at the end, inside the layout that you're working:
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="200dp"
android:layout_height="200dp"
android:indeterminate="false"
android:progressDrawable="#drawable/circular_progress_bar"
android:background="#drawable/circle_shape"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:progress="65" />
Here's the result:
Long Answer:
Use a custom view which inherits the android.view.View
Here is the full project on github
With the Material Components Library you can use the CircularProgressIndicator:
Something like:
<com.google.android.material.progressindicator.CircularProgressIndicator
app:indicatorColor="#color/...."
app:trackColor="#color/...."
app:indicatorSize="64dp"/>
You can use these attributes:
indicatorSize: defines the radius of the circular progress indicator
trackColor: the color used for the progress track. If not defined, it will be set to the indicatorColor and apply the android:disabledAlpha from the theme.
indicatorColor: the single color used for the indicator in determinate/indeterminate mode. By default it uses theme primary color
Use progressIndicator.setProgressCompat((int) value, true); to update the value in the indicator.
Note: it requires at least the version 1.3.0-alpha04.
I have done with easy way:
Please check screen shot for the same.
CustomProgressBarActivity.java:
public class CustomProgressBarActivity extends AppCompatActivity {
private TextView txtProgress;
private ProgressBar progressBar;
private int pStatus = 0;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_progressbar);
txtProgress = (TextView) findViewById(R.id.txtProgress);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
new Thread(new Runnable() {
#Override
public void run() {
while (pStatus <= 100) {
handler.post(new Runnable() {
#Override
public void run() {
progressBar.setProgress(pStatus);
txtProgress.setText(pStatus + " %");
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
pStatus++;
}
}
}).start();
}
}
activity_custom_progressbar.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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.skholingua.android.custom_progressbar_circular.MainActivity" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:layout_height="wrap_content">
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:indeterminate="false"
android:max="100"
android:progress="0"
android:progressDrawable="#drawable/custom_progressbar_drawable"
android:secondaryProgress="0" />
<TextView
android:id="#+id/txtProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/progressBar"
android:layout_centerInParent="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</RelativeLayout>
custom_progressbar_drawable.xml:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="-90"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270" >
<shape
android:shape="ring"
android:useLevel="false" >
<gradient
android:centerY="0.5"
android:endColor="#FA5858"
android:startColor="#0099CC"
android:type="sweep"
android:useLevel="false" />
</shape>
</rotate>
Hope this will help you.
I have written detailed example on circular progress bar in android here on my blog demonuts.com. You can also fond full source code and explanation there.
Here's how I made circular progressbar with percentage inside circle in pure code without any library.
first create a drawable file called circular.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/secondaryProgress">
<shape
android:innerRadiusRatio="6"
android:shape="ring"
android:thicknessRatio="20.0"
android:useLevel="true">
<gradient
android:centerColor="#999999"
android:endColor="#999999"
android:startColor="#999999"
android:type="sweep" />
</shape>
</item>
<item android:id="#android:id/progress">
<rotate
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270">
<shape
android:innerRadiusRatio="6"
android:shape="ring"
android:thicknessRatio="20.0"
android:useLevel="true">
<rotate
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
<gradient
android:centerColor="#00FF00"
android:endColor="#00FF00"
android:startColor="#00FF00"
android:type="sweep" />
</shape>
</rotate>
</item>
</layer-list>
Now in your activity_main.xml add following:
<?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"
android:background="#color/dialog"
tools:context="com.example.parsaniahardik.progressanimation.MainActivity">
<ProgressBar
android:id="#+id/circularProgressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="250dp"
android:layout_height="250dp"
android:indeterminate="false"
android:max="100"
android:progress="50"
android:layout_centerInParent="true"
android:progressDrawable="#drawable/circular"
android:secondaryProgress="100"
/>
<ImageView
android:layout_width="90dp"
android:layout_height="90dp"
android:background="#drawable/whitecircle"
android:layout_centerInParent="true"/>
<TextView
android:id="#+id/tv"
android:layout_width="250dp"
android:layout_height="250dp"
android:gravity="center"
android:text="25%"
android:layout_centerInParent="true"
android:textColor="#color/colorPrimaryDark"
android:textSize="20sp" />
</RelativeLayout>
In activity_main.xml I have used one circular image with white background to show white background around percentage. Here is the image:
You can change color of this image to set custom color around percentage text.
Now finally add following code to MainActivity.java :
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.animation.DecelerateInterpolator;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
int pStatus = 0;
private Handler handler = new Handler();
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.circular);
final ProgressBar mProgress = (ProgressBar) findViewById(R.id.circularProgressbar);
mProgress.setProgress(0); // Main Progress
mProgress.setSecondaryProgress(100); // Secondary Progress
mProgress.setMax(100); // Maximum Progress
mProgress.setProgressDrawable(drawable);
/* ObjectAnimator animation = ObjectAnimator.ofInt(mProgress, "progress", 0, 100);
animation.setDuration(50000);
animation.setInterpolator(new DecelerateInterpolator());
animation.start();*/
tv = (TextView) findViewById(R.id.tv);
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (pStatus < 100) {
pStatus += 1;
handler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
mProgress.setProgress(pStatus);
tv.setText(pStatus + "%");
}
});
try {
// Sleep for 200 milliseconds.
// Just to display the progress slowly
Thread.sleep(8); //thread will take approx 1.5 seconds to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
If you want to make horizontal progressbar, follow this link, it has many valuable examples with source code:
http://www.skholingua.com/android-basic/user-interface/form-widgets/progressbar
I realized a Open Source library on GitHub CircularProgressBar that does exactly what you want the simplest way possible:
USAGE
To make a circular ProgressBar add CircularProgressBar in your layout XML and add CircularProgressBar library in your projector or you can also grab it via Gradle:
compile 'com.mikhaellopez:circularprogressbar:1.0.0'
XML
<com.mikhaellopez.circularprogressbar.CircularProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:background_progressbar_color="#FFCDD2"
app:background_progressbar_width="5dp"
app:progressbar_color="#F44336"
app:progressbar_width="10dp" />
You must use the following properties in your XML to change your CircularProgressBar.
Properties:
app:progress (integer) >> default 0
app:progressbar_color (color) >> default BLACK
app:background_progressbar_color (color) >> default GRAY
app:progressbar_width (dimension) >> default 7dp
app:background_progressbar_width (dimension) >> default 3dp
JAVA
CircularProgressBar circularProgressBar = (CircularProgressBar)findViewById(R.id.yourCircularProgressbar);
circularProgressBar.setColor(ContextCompat.getColor(this, R.color.progressBarColor));
circularProgressBar.setBackgroundColor(ContextCompat.getColor(this, R.color.backgroundProgressBarColor));
circularProgressBar.setProgressBarWidth(getResources().getDimension(R.dimen.progressBarWidth));
circularProgressBar.setBackgroundProgressBarWidth(getResources().getDimension(R.dimen.backgroundProgressBarWidth));
int animationDuration = 2500; // 2500ms = 2,5s
circularProgressBar.setProgressWithAnimation(65, animationDuration); // Default duration = 1500ms
Fork or Download this library here >> https://github.com/lopspower/CircularProgressBar
Here is a simple customview for display circle progress. You can modify and optimize more to suitable for your project.
class CircleProgressBar #JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val backgroundWidth = 10f
private val progressWidth = 20f
private val backgroundPaint = Paint().apply {
color = Color.LTGRAY
style = Paint.Style.STROKE
strokeWidth = backgroundWidth
isAntiAlias = true
}
private val progressPaint = Paint().apply {
color = Color.RED
style = Paint.Style.STROKE
strokeWidth = progressWidth
isAntiAlias = true
}
var progress: Float = 0f
set(value) {
field = value
invalidate()
}
private val oval = RectF()
private var centerX: Float = 0f
private var centerY: Float = 0f
private var radius: Float = 0f
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
centerX = w.toFloat() / 2
centerY = h.toFloat() / 2
radius = w.toFloat() / 2 - progressWidth
oval.set(centerX - radius,
centerY - radius,
centerX + radius,
centerY + radius)
super.onSizeChanged(w, h, oldw, oldh)
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.drawCircle(centerX, centerY, radius, backgroundPaint)
canvas?.drawArc(oval, 270f, 360f * progress, false, progressPaint)
}
}
Example using
xml
<com.example.androidcircleprogressbar.CircleProgressBar
android:id="#+id/circle_progress"
android:layout_width="200dp"
android:layout_height="200dp" />
kotlin
class MainActivity : AppCompatActivity() {
val TOTAL_TIME = 10 * 1000L
override fun onCreate(savedInstanceState: Bundle?) {
...
timeOutRemoveTimer.start()
}
private var timeOutRemoveTimer = object : CountDownTimer(TOTAL_TIME, 10) {
override fun onFinish() {
circle_progress.progress = 1f
}
override fun onTick(millisUntilFinished: Long) {
circle_progress.progress = (TOTAL_TIME - millisUntilFinished).toFloat() / TOTAL_TIME
}
}
}
Result
I'm new so I can't comment but thought to share the lazy fix. I use Pedram's original approach as well, and just ran into the same Lollipop issue. But alanv over in another post had a one line fix. Its some kind of bug or oversight in API21. Literally just add android:useLevel="true" to your circle progress xml. Pedram's new approach is still the proper fix, but I just thought I share the lazy fix as well.
<?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">
<ProgressBar
android:id="#+id/progress_circular_id"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:indeterminate="false"
android:progress="30"
android:progressDrawable="#drawable/circular_progress_bar"
android:background="#drawable/circle_shape"
style="?android:attr/progressBarStyleHorizontal"
android:max="100">
</ProgressBar>
<TextView
android:id="#+id/textview_progress_status_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="50%"
android:layout_centerInParent="true"
android:textStyle="bold"
android:textColor="#color/blue"
android:textSize="35dp">
</TextView>
<Button
android:id="#+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="click me"
android:textColor="#color/white"
android:layout_below="#+id/progress_circular_id"
android:layout_centerHorizontal="true"
>
</Button>
</RelativeLayout>
Create a Drawable File with name circle_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:innerRadiusRatio="2.5"
android:thickness="25dp"
android:useLevel="false">
<solid android:color="#CCC" />
</shape>
Create a file with circular_progress_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="270"
android:toDegrees="270">
<shape
android:innerRadiusRatio="2.5"
android:shape="ring"
android:thickness="25dp"
android:useLevel="true"><!-- this line fixes the issue for lollipop api 21 -->
<gradient
android:angle="0"
android:endColor="#007DD6"
android:startColor="#007DD6"
android:type="sweep"
android:useLevel="false" />
</shape>
</rotate>
In java File For example purpose used fragmet.
public class FragmentRegistration extends BaseFragmentHelper {
View registrationFragmentView;
ProgressBar progressBar;
Button button;
int count=0;
#Override
public void onAttachFragment(#NonNull Fragment childFragment) {
super.onAttachFragment(childFragment);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
registrationFragmentView = inflater.inflate(R.layout.new_device_registration, container, false);
progressBar=(ProgressBar)registrationFragmentView.findViewById(R.id.progress_circular_id);
button=(Button) registrationFragmentView.findViewById(R.id.check);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
count=count+10;
progressBar.setProgress(count);
}
});
return registrationFragmentView;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onDetach() {
super.onDetach();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
}
try this method to create a bitmap and set it to image view.
private void circularImageBar(ImageView iv2, int i) {
Bitmap b = Bitmap.createBitmap(300, 300,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
Paint paint = new Paint();
paint.setColor(Color.parseColor("#c4c4c4"));
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(150, 150, 140, paint);
paint.setColor(Color.parseColor("#FFDB4C"));
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.FILL);
final RectF oval = new RectF();
paint.setStyle(Paint.Style.STROKE);
oval.set(10,10,290,290);
canvas.drawArc(oval, 270, ((i*360)/100), false, paint);
paint.setStrokeWidth(0);
paint.setTextAlign(Align.CENTER);
paint.setColor(Color.parseColor("#8E8E93"));
paint.setTextSize(140);
canvas.drawText(""+i, 150, 150+(paint.getTextSize()/3), paint);
iv2.setImageBitmap(b);
}
#Pedram, your old solution works actually fine in lollipop too (and better than new one since it's usable everywhere, including in remote views) just change your circular_progress_bar.xml code to this:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="270"
android:toDegrees="270">
<shape
android:innerRadiusRatio="2.5"
android:shape="ring"
android:thickness="1dp"
android:useLevel="true"> <!-- Just add this line -->
<gradient
android:angle="0"
android:endColor="#007DD6"
android:startColor="#007DD6"
android:type="sweep"
android:useLevel="false" />
</shape>
</rotate>
https://github.com/passsy/android-HoloCircularProgressBar is one example of a library that does this. As Tenfour04 stated, it will have to be somewhat custom, in that this is not supported directly out of the box. If this library doesn't behave as you wish, you can fork it and modify the details to make it work to your liking. If you implement something that others can then reuse, you could even submit a pull request to get that merged back in!
Change
android:useLevel="false"
to
android:useLevel="true"
for second sahpe with id="#android:id/progress
hope it works
package com.example.ankitrajpoot.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private ProgressBar spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner=(ProgressBar)findViewById(R.id.progressBar);
spinner.setVisibility(View.VISIBLE);
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="48dp"
style="?android:attr/progressBarStyleLarge"
android:layout_height="48dp"
android:indeterminateDrawable="#drawable/circular_progress_bar"
android:indeterminate="true" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="1080">
<shape
android:shape="ring"
android:innerRadiusRatio="3"
android:thicknessRatio="8"
android:useLevel="false">
<size
android:width="56dip"
android:height="56dip" />
<gradient
android:type="sweep"
android:useLevel="false"
android:startColor="#android:color/transparent"
android:endColor="#1e9dff"
android:angle="0"
/>
</shape>
</rotate>
Good news is that now material design library supports determinate circular progress bars too:
<com.google.android.material.progressindicator.CircularProgressIndicator
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
For more info about this refer here.
if you want to set progress in an anti-clock direction then use below image for set fromDegree and toDegree's values in progressDrawble xml.
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="270"
android:toDegrees="-90">
<shape
android:innerRadiusRatio="2"
android:shape="ring"
android:thickness="1dp">
<gradient
android:angle="0"
android:endColor="#007DD6"
android:startColor="#007DD6"
android:type="sweep" />
</shape>
</rotate>
This code will let your progress anti-clockwise and from the top.
Change the degrees as per the above image from where you want to rotate your progress bar.
You can use this library https://github.com/xYinKio/ArcCircleProgressBar
This is one of the most flexible circular progress bars
This picture is showing the lib powers

How do I change the color of icon of the selected tab of TabLayout?

I'm using a TabLayout with a ViewPager and I'm wondering how I can most efficiently change the color of the icon of the selected tab in the TabLayout.
A perfect reference for how this is implemented is Google's Youtube app. On the main page, there are four icons that are colored dark gray. When a specific tab is selected, the tab's icon becomes white.
Without any third party libraries, how can I achieve the same effect?
One possible solution is apparently with selectors. But in that case, I would have to find both a white and a gray version of the icon and then switch the icon when the tab becomes selected or deselected. I'm wondering if there's a more effective method where I can just highlight the icon color or something. I haven't been able to find this in any tutorial.
EDIT
The solution that I mention directly above requires the use of two drawables for each tab's icon. I'm wondering if there's a way I can do it programmatically with ONE drawable for each tab's icon.
I found a way that can be easy.
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(
new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
int tabIconColor = ContextCompat.getColor(context, R.color.tabSelectedIconColor);
tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
super.onTabUnselected(tab);
int tabIconColor = ContextCompat.getColor(context, R.color.tabUnselectedIconColor);
tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
super.onTabReselected(tab);
}
}
);
This can be done very simply, entirely in xml.
Add one line to your TabLayout in your xml, app:tabIconTint="#color/your_color_selector", as below:
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIconTint="#color/your_color_selector"
app:tabIndicatorColor="#color/selected_color"/>
Then, create a color selector file (named "your_color_selector.xml" above) in res/color directory:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/selected_color" android:state_selected="true"/>
<item android:color="#color/unselected_color"/>
</selector>
This assumes you have 2 colors, "selected_color" and "unselected_color" in your colors.xml file.
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
tabLayout.getTabAt(3).setIcon(tabIcons[3]);
tabLayout.getTabAt(0).getIcon().setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(1).getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(2).getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(3).getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
tab.getIcon().setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
tab.getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
You can use a ColorStateList.
First, create an xml file (e.g. /color/tab_icon.xml) that looks like this and defines the different tints for different states:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/icon_light"
android:state_selected="true" />
<item android:color="#color/icon_light_inactive" />
</selector>
Then add this to your code:
ColorStateList colors;
if (Build.VERSION.SDK_INT >= 23) {
colors = getResources().getColorStateList(R.color.tab_icon, getTheme());
}
else {
colors = getResources().getColorStateList(R.color.tab_icon);
}
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
Drawable icon = tab.getIcon();
if (icon != null) {
icon = DrawableCompat.wrap(icon);
DrawableCompat.setTintList(icon, colors);
}
}
First, you grab the ColorStateList from your XML (the method without theme is deprecated, but necessary for pre-Marshmallow devices). Then you set for each tab's icon it's TintList to the ColorStateList; use DrawableCompat (support library) to support older versions as well.
That's it!
For it You'll have to customize tab icons using selector class for each Tab like:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/advisory_selected" android:state_selected="true" />
<item android:drawable="#drawable/advisory_normal" android:state_selected="false" />
Add this under res > colors directory:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#android:color/holo_orange_dark"/>
<item android:color="#android:color/holo_red_light"/>
</selector>
Add code in tab view in xml:
app:tabIconTint="#color/selector_tab"
Why don't you use icon fonts (like font awesome) for your icons? then change the font of tab text to your desirable font icon .ttf and enjoy change selected text color to your tab icons!
I, myself, used this method and it is really nice and clean :)
firstly, set up the titles from your desired icon font:
in string.xml:
<string name="ic_calculator"></string>
<string name="ic_bank"></string>
then in MainActivity.Java:
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentBank(), getString(R.string.ic_bank));
adapter.addFragment(new FragmentCalculate(), getString(R.string.ic_calculator));
viewPager.setAdapter(adapter);
}
Then you should change the font of Tab titles to font-awesome:
Typeface typeFaceFont = Typeface.createFromAsset(getAssets(), "fontawesome-webfont.ttf");
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(typeFaceFont);
}
}
}
and last but not least, in your related .xml file, set color for your tabTextColor and tabSelectedTextColor:
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="horizontal"
android:background="#color/colorPrimaryDark"
app:tabSelectedTextColor="#color/colorAccent"
app:tabTextColor="#color/textColorPrimary"
app:tabIndicatorColor="#color/colorAccent"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.TabLayout>
and in colors.xml:
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="colorHighlight">#FFFFFF</color>
<color name="textColorPrimary">#E1E3F3</color>
</resources>
check the following code. Customise your icon one is color and another one is no color.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/mybookings_select" android:state_selected="true"/><!-- tab is selected(colored icon)-->
<item android:drawable="#drawable/mybookings" /><!-- tab is not selected(normal no color icon)-->
On reference to the second answer which shows how to set color separately, many people might be wondering around how to remove the color of the first icon while switching to next one. What you can do is go like this :
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
tabLayout.getTabAt(3).setIcon(tabIcons[3]);
tabLayout.getTabAt(0).getIcon().setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(1).getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(2).getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(3).getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
tab.getIcon().setColorFilter(Color.GREEN,PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
//for removing the color of first icon when switched to next tab
tablayout.getTabAt(0).getIcon().clearColorFilter();
//for other tabs
tab.getIcon().clearColorFilter();
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});}
I would have commented on the second answer but did not have enough reputations for that! Sorry. But please follow that you'd save your time and your headache! Happy learning
You can use addOnTabSelectedListener, it works for me.
tablayout = findViewById(R.id.viewall_tablayout);
pager = findViewById(R.id.viewall_pager);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragments(new RestFragment(),"Restaurant");
adapter.addFragments(new BarFragment(),"Bar");
adapter.addFragments(new HotelFragment(),"Hotel");
adapter.addFragments(new CoffeeFragment(),"Coffee Shop");
pager.setAdapter(adapter);
tablayout.setupWithViewPager(pager);
tablayout.getTabAt(0).setIcon(R.drawable.ic_restaurant);
tablayout.getTabAt(1).setIcon(R.drawable.ic_glass_and_bottle_of_wine);
tablayout.getTabAt(2).setIcon(R.drawable.ic_hotel_black_24dp);
tablayout.getTabAt(3).setIcon(R.drawable.ic_hot_coffee);
tablayout.getTabAt(0).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.getTabAt(1).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.getTabAt(2).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.getTabAt(3).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
tab.getIcon().setTint(getResources().getColor(R.color.colorPrimary,getTheme()));
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
tab.getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
For change tint even you can set same color what ever you drawble tab icon have
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:background="#color/bgFrag"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_gravity="bottom"
app:tabGravity="fill"
app:tabTextColor="#drawable/tab_search_text_clr"
app:tabIconTintMode="multiply"
app:tabIconTint="#ffffff"
app:tabIndicator="#null"
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
app:tabInlineLabel="true"
app:tabMode="fixed" >
</com.google.android.material.tabs.TabLayout>
tab_search_text_clr.xml
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#ffffff"/> <!-- checked -->
<item android:state_selected="true" android:color="#ffffff"/> <!-- checked -->
<item android:color="#acacac"/><!-- anything else -->
</selector>
The ColorStateList only has two entries: android.R.attr.state_selected and the default wildcard. These can be defined eg. with src/main/res/xml/tab_layout_color_state.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/colorAccent" android:state_selected="true"/>
<item android:color="#color/white"/>
</selector>
Then R.xml.tab_layout_color_state can be applied as a ColorStateList:
private void applyColorStateList(#NonNull TabLayout tabLayout, int resId) {
tabLayout.setTabIconTint(requireContext().getColorStateList(resId));
}
One possible way of "Highlighting" the icon is to access the image view and set the color filter. Try using the setColorFilter(int color) ImageView method and applying the color white.
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {...}
Has been deprecated. Rather Use
tabLayout.addOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
int tabIconColor = ContextCompat.getColor(context, R.color.tabSelectedIconColor);
tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
int tabIconColor = ContextCompat.getColor(context, R.color.tabUnselectedIconColor);
tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
I know this is a bit old, but I was just facing the same issue and it seems that the answers here are outdated.
Use a color state list and add it directly to the TabLayout XML element
Given the tab_icon.xml file below:-
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/colorPrimary" android:state_selected="true" />
<item android:color="#android:color/darker_gray" />
</selector>
And the TabLayout XML element (notice the tabIconTint attr)
<com.google.android.material.tabs.TabLayout
android:id="#+id/favourites_selectionTL"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabIconTint="#color/tab_icon"
app:tabIndicatorColor="#color/colorPrimary"
app:tabInlineLabel="true"
app:tabSelectedTextColor="#color/colorPrimary" />
That's it.
Extending my prefered answer with the ColorStateList from here, you can use the following solution if you are using custom tabs.
Set up tabs in your activity's xml
...
<android.support.design.widget.TabLayout
android:id="#+id/main_tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="#layout/nav_bar_tab_item"/>
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="#layout/nav_bar_tab_item"/>
</android.support.design.widget.TabLayout>
...
And custom tab layout nav_bar_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="#+id/nav_bar_item_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingEnd="#dimen/_5sdp"
android:paddingStart="#dimen/_5sdp">
<ImageView
android:id="#+id/item_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/item_description"
android:layout_width="wrap_content"
android:gravity="center"
<!-- Use selector here to change the text color when selected/unselected -->
android:textColor="#color/nav_bar_icons_color"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/item_img"/>
</android.support.constraint.ConstraintLayout>
In your activity
tabLayout = findViewById(R.id.main_tablayout);
ConstraintLayout navMyHotelLayout = (ConstraintLayout) tabLayout.getTabAt(0)
.getCustomView();
tab1Icon = navMyHotelLayout.findViewById(R.id.item_img);
tab1TextView = navMyHotelLayout.findViewById(R.id.item_description);
tab1Icon.setImageResource(R.drawable.ic_tab1);
// Use the selector here to change the color when selected/unselected
tintImageViewSelector(tab1Icon, R.color.nav_bar_icons_color);
tab1TextView.setText("tab 1");
ConstraintLayout navTtdLayout = (ConstraintLayout) tabLayout.getTabAt(1)
.getCustomView();
tab2Icon = navTtdLayout.findViewById(R.id.item_img);
tab2View = navTtdLayout.findViewById(R.id.item_description);
tab2Icon.setImageResource(R.drawable.ic_tab2);
tintImageViewSelector(tab2Icon, R.color.nav_bar_icons_color);
tab2TextView.setText("tab 2");
And add these helper functions for the change of color
public static void tintDrawableSelector(Drawable vd, final #ColorRes int clrRes, Context context) {
DrawableCompat.setTintList(vd, ContextCompat.getColorStateList(context, clrRes));
}
public static void tintImageViewSelector(ImageView imgView, final #ColorRes int clrRes, Context context) {
tintDrawableSelector(imgView.getDrawable(), clrRes);
}
Finally, the selector nav_bar_icons_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#android:color/white" android:state_checked="true"/>
<item android:color="#android:color/white" android:state_selected="true"/>
<item android:color="#android:color/black"/>
</selector>
Check the following code:
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
if(tab.getPosition() == 0){
tabLayout.getTabAt(0).setIcon(tabIcons1[0]);
}
if(tab.getPosition() == 1){
tabLayout.getTabAt(1).setIcon(tabIcons1[1]);
}
if(tab.getPosition() == 2){
tabLayout.getTabAt(2).setIcon(tabIcons1[2]);
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
You can change the text color of selected tab using the following xml attribute of Tab layout :
app:tabSelectedTextColor="your desired color"
To customize your icon color of selected tab you need to use selector
Create a xml file under drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="selected_item_color" android:state_activated="true" />
<item android:color="unselected_item_color" />
</selector>
and add this selector to tab layout xml attribute like below:
app:tabIconTint="#drawable/name_of_file"
Perform the following steps respectively.
app/src/main/res/values/colors.xml (Add to colors.xml)
<color name="icon_enabled">#F3D65F</color>
<color name="icon_disabled">#FFFFFF</color>
app/src/main/res/color/custom_tab_icon.xml (Create a folder named color in res. Create a custom tab icon.xml in the folder.)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/icon_enabled" android:state_selected="true"/>
<item android:color="#color/icon_disabled" android:state_selected="false"/>
</selector>
app/src/main/res/drawable/ic_action_settings.png (Create)
double click on action_settings to add
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="21.6"
android:viewportHeight="21.6"
android:tint="#color/custom_tab_icon">
<group android:translateX="-1.2"
android:translateY="-1.2">
<path
android:fillColor="#FF000000"
android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
</group>
</vector>

Android animation fade in / fade out is not setting the visibility of the view in the callback function

I have android view that I want to fadeIn and Fadeout when users click on a button. The animation itself is being called and the callback is being called but when the animation triggers the view cannot be seen. I think the problem is with the xml layout, I have been stuck on this for hours if someone can help it would be greatly appreciated.
My Main Layout: - Just view in question
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="left|top"
android:background="#color/whiteOverlay"
android:gravity="center_vertical|center_horizontal"
android:id="#+id/uploadOptions"
android:alpha="0"
android:visibility="gone">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="40dp"
android:paddingRight="40dp">
<Button
style = "#style/basic_button"
android:text="#string/selectFromGallery"
android:id="#+id/gallery_select"
android:layout_marginTop="10dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
style = "#style/basic_button"
android:text="#string/selectFromCamera"
android:id="#+id/camera_select"
android:layout_marginTop="10dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</LinearLayout>
FadeIn
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="500" />
</set>
FadeOut
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="500" />
</set>
Activity Java -
public class regPP extends Activity {
private String lang = "";
private Boolean optionsActive = false;
private LinearLayout options = null;
private void fade (final View view, final Boolean Toggle){
Animation anim;
view.setVisibility(View.VISIBLE);
if(Toggle){
//fadeOut
anim = AnimationUtils.loadAnimation(regPP.this, R.anim.fadeout);
Log.d("FADE","FadeOut");
} else {
//fadeIn
anim = AnimationUtils.loadAnimation(regPP.this, R.anim.fadein);
Log.d("FADE","FadeIn");
}
view.startAnimation(anim);
anim.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation arg0) {
//Functionality here
if(Toggle){
view.setVisibility(View.GONE);
Log.d("FADE", "FadeOut Callback");
} else {
view.setVisibility(View.VISIBLE);
Log.d("FADE", "FadeIn Callback");
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.lang = getResources().getString(R.string.lang);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
final Context context = regPP.this;
setContentView(R.layout.reg_pp);
ImageButton uploadTog = (ImageButton) findViewById(R.id.uploadTog);
options = (LinearLayout) findViewById(R.id.uploadOptions);
uploadTog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fade(options,false);
optionsActive = true;
}
});
}
#Override
public void onBackPressed() {
if(optionsActive){
fade(options,true);
optionsActive = false;
} else {
super.onBackPressed();
}
}
}
remove this line may help u
android:visibility="gone"
visibility is gone that's why your view is not visible
android:visibility="gone"

Animated textView change the text and animate again (animated countdown)

I am trying to make an animated countdown on android plataform, that show de number 3 in textView growing up from 0 to 1.5 on scale property, so the number 2, 1 and "GO!".
I'm using a textView, an Animation and an AnimationListener, but the animation doesn't work as I want, it works just in first animation showing number 3, so it shows the word "go!" without animating.
What am I doing wrong?
Thanks!
Here the View counter.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_height="fill_parent"
android:layout_width="fill_parent" android:gravity="center_vertical|center_horizontal">
<TextView
android:id="#+id/txtCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3" android:textColor="#ffffff" android:textSize="150dp"/>
</LinearLayout>
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/linear_interpolator"
android:fromXScale="0"
android:toXScale="1.5"
android:fromYScale="0"
android:toYScale="1.5"
android:fillAfter="false"
android:duration="1000" />
</set>
My code:
public class AdivinhacaoActivity extends Activity {
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
//async task
new loaderImages(this).execute();
}
private class loaderImages extends AsyncTask<Void, String, Bitmap[]> {
Activity activity;
public loaderImages(Activity act){
activity = act;
}
protected Bitmap[] doInBackground(Void... arg0) {
...
return list;
}
...
int countCounter;
protected void onPostExecute(Bitmap[] imagens){
bmps = imagens;
carregaContagem();
final Animation anima = AnimationUtils.loadAnimation(activity, R.anim.counter);
countCounter = 3;
anima.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation anim){};
public void onAnimationRepeat(Animation anim){};
public void onAnimationEnd(Animation anim)
{
//here I tried txtCount.clearAnimation() but it doesn't work
countCounter--;
if(countCounter >= 0){
//change the text
if(countCounter > 0){
txtCount.setText("" + countCounter);
}
else{
txtCount.setText("GO!");
}
//start animation again with text changed
txtCount.startAnimation(anim);
}
else{
...
}
};
});
//start animation first time
txtCount.startAnimation(anima);
}
}
}
I managed solve my problem, using one textView and one animation instance for each count, yes it works, but I couldn't understand why reason my original solution didn't work!

ValueAnimator to change background color

I want to create a screen with a backgroundcolor that keeps changing from red to blue. For some reason it always crashes when i try to instantiate the ValueAnimator. I have no idea what's wrong with my code
Thank you
Animation class
public BackgroundAnimation(Context context){
super(context);
ValueAnimator colorAnim = ObjectAnimator.ofInt(R.anim.animator, "backgroundColor", Color.RED, Color.BLUE);
colorAnim.setDuration(3000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();
}
animator.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="backgroundColor"/>
</set>
Main class
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.menu);
LinearLayout container = (LinearLayout) findViewById(R.id.container);
container.addView(new BackgroundAnimation(this));
}
main.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:orientation="vertical">
<TextView
android:id="#+id/TextView01"
android:gravity="center"
android:textSize="20sp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/TextView02"
android:gravity="center"
android:textSize="20sp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<ImageView
android:id="#+id/ImageView01"
android:layout_width="fill_parent"
android:layout_height="300sp"/>
</LinearLayout>
You can use the ObjectAnimator to change the background color:
For API >= 21 :
ObjectAnimator colorAnimator = ObjectAnimator.ofArgb(travelersListView.getBackground().mutate(), "tint", mCurrentBackground, mFadeColor);
colorAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
colorAnimator.start();
For backward support from API 16 use this:
ObjectAnimator colorAnimator = ObjectAnimator.ofObject(travelersListView.getBackground().mutate(), "tint", new ArgbEvaluator(), mCurrentBackground, mFadeColor);
colorAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
colorAnimator.start();
There is not id parameter in XML file for LinearLayout.
<?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:orientation="vertical"
android:id="#+id/container">
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.menu);
LinearLayout container = (LinearLayout) findViewById(R.id.container);
changeBackground(container, "#F44336", "#2196F3"); //#F44336 : Red , #2196F3 : Blue
}
public void changeBackground(final View view, String color1, String color2) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(Color.parseColor(color1), Color.parseColor(color2));
anim.setEvaluator(new ArgbEvaluator());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
view.setBackgroundColor((Integer) valueAnimator.getAnimatedValue());
}
});
anim.setDuration(2000);
anim.setRepeatCount(ValueAnimator.INFINITE);
anim.setRepeatMode(ValueAnimator.REVERSE);
anim.start();
}
Try this, Hope this helps
No variant of ObjectAnimator.ofInt() takes resource ID as parameter. Please read this for declaring animations in XML. http://developer.android.com/guide/topics/graphics/prop-animation.html#declaring-xml

Categories

Resources