I'm creating an animation in View. After the user click button that become as circle. I'm using Scale animation to archive this. but my view layout radius change after click the button. how can i keep the same radius during the animation or are they anyway to achieve this without libraries ?
view xml
<View
android:id="#+id/containerView"
android:layout_width="363dp"
android:layout_height="45dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="188dp"
android:background="#drawable/login_boader_round"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.333"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/login_screen_credential_view_holder" />
login_boader_round xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:pivotX="100%"
android:pivotY="100%"
android:radius="45dp"
/>
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
<solid android:color="#677FFF" />
<!--<stroke-->
<!-- android:width="3dp"-->
<!-- android:color="#50A4D1" />-->
</shape>
After the button click event
public void scaleViewAnimation(View view) {
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 0, 1f, 1f, Animation.RESTART, 0.5f, Animation.RESTART, 0.5f);
scaleAnimation.setDuration(ANIMATION_FADE_DURATION);
scaleAnimation.setFillAfter(true);
view.startAnimation(scaleAnimation);
}
ScaleAnimation class does not have that property. so i used ValueAnimator class to active this. ANIMATION_TIME is an integer. you want to give
ValueAnimator anim = ValueAnimator.ofInt(view.getMeasuredWidth(), view.getMeasuredHeight());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = val;
view.requestLayout();
}
});
anim.setDuration(ANIMATION_TIME);
anim.start();
Related
I have a Textview with an XML file attached to the background. Now I wanted to change the background of the Textview with setBackgroundColor(), but it doesn't work, because the background color of the XML file has to be changed. How do I change the background color of the my_border XML file?
XML Textview:
<TextView
android:id="#+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:background="#drawable/my_border"
android:text="Hey"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
XML Textview Border file:
<?xml version="1.0" encoding="utf-8"?>
<!-- View background color -->
<solid
android:color="#fff" >
</solid>
<!-- View border color and width -->
<stroke
android:width="1dp"
android:color="#000" >
</stroke>
<!-- The radius makes the corners rounded -->
<corners
android:radius="5dp" >
</corners>
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp">
</padding>
try this method
private void recolor(Context context, TextView textView, #ColorInt int color,int drawableResourceId) {
Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, drawableResourceId);
if (unwrappedDrawable != null) {
DrawableCompat.wrap(unwrappedDrawable);
DrawableCompat.setTint(unwrappedDrawable, color);
textView.setBackground(unwrappedDrawable);
}
}
lets say you want a red background for your TextView then this will be as following
TextView mTextView = findViewById(R.id.textView7);
recolor(this, mTextView , getResources().getColor(R.color.red),R.drawable.my_border);
Following the tips given in this thread I'm setting the bottom margin of a snackbar to ca. 55 dp in order to have it above the FAB.
The code is - as in the other question:
Snackbar snackbar = Snackbar.make(constraintLayoutContent, msg, Snackbar.LENGTH_LONG);
snackbar.setAction(action, v -> snackbar.dismiss());
View snackBarView = snackbar.getView();
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) snackBarView.getLayoutParams();
params.setMargins(params.leftMargin,
params.topMargin,
params.rightMargin,
params.bottomMargin + 500);
//params.gravity = Gravity.TOP;
snackBarView.setLayoutParams(params);
snackbar.show();
The problem I'm facing is that if the snackbar is at the bottom of the screen (params.gravity = Gravity.BOTTOM;) the bottom margin is not applied; however if the snackbar is placed at top of the screen (params.gravity = Gravity.TOP; params.topMargin = 500;) the top margin is correctly applied.
Two screenshots of the issue:
top margin correctly applied
bottom margin not applied
Thanks for your help.
EDIT:
The following is my layout xml file. Not sure if this could help, but here we are.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayoutContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/constraintLayoutContent">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
M.Usman version works for me:
val snackBarView = snackbar.view
snackBarView.translationY = (-getNavigationBarSize(context)).toFloat()
snackbar.show()
#JvmStatic
fun getNavigationBarSize(context: Context): Int {
val resources = context.resources
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
return if (resourceId > 0) {
resources.getDimensionPixelSize(resourceId)
} else getDensity(context).toInt() * 56
}
Adding CoordinatorLayout or Frame Layout and then setting margin didn't work for me
To tackle this problem use Drawable Background where use item to set Margin and shape to set desired Padding
container_snackbar.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Set Margin Here -->
<item
android:left="20dp"
android:right="20dp"
android:bottom="10dp"
android:top="10dp">
<!-- Insert your shape here: -->
<shape android:shape="rectangle" >
<solid android:color="#FE4C4C" />
<!-- Padding for inner text-->
<padding android:left="25dp" android:right="10dp" android:bottom="10dp" android:top="10dp" />
<corners android:radius="5dp" />
</shape>
</item>
</layer-list>
And then from Activity set that Drawable
MainActivity.java
Snackbar snack = Snackbar
.make(activity,"Hello World 🚀",Snackbar.LENGTH_INDEFINITE);
snack.getView()
.setBackground(ContextCompat.getDrawable(getApplicationContext(),R.drawable.contianer_snackbar));
snack.show();
Result
I am facing a similar issue. Looks like margin bottom only works when you pass CoordinatorLayoutView to Snackbar.make().
I think it has to do with baseTransientBottomBar and most of its behavior such as swipe-to-dismiss will be available after you pass CoordinatorLayoutView. Maybe it's possible to override baseTransientBottomBar for it to apply margin-bottom.
Just add this code/call this function after snack.show()
...
snack.show()
snack.setAnimToUnblockBottomNavBar()
...
private fun Snackbar.setAnimToUnblockBottomNavBar() {
val animator = ValueAnimator.ofInt(0, 150)
animator.addUpdateListener { valueAnimator ->
val valueAnim = valueAnimator.animatedValue
if (valueAnim is Int) {
try {
val snackBarView: View = this.view
val params = snackBarView.layoutParams as FrameLayout.LayoutParams
params.setMargins(0, 0, 0, valueAnim)
snackBarView.layoutParams = params
} catch (_: Exception) { /* do nothing */ }
}
}
animator.start()
}
I have xml gradient drawable resource file here:
file: fg_graidient
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:centerX="0%"
android:startColor="#00020321"
android:centerColor="#F2000000"
android:endColor="#B2020321"
android:angle="45"/>
</shape>
I can the imageview foreground like below:
<ImageView
android:id="#+id/backimg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:foreground="#drawable/fg_graidient"
/>
But I want to set this drawable foreground for imageview programmatically. Is it possible?
Create programmatically gradient shapes
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
#Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(0, 0, width, height,
new int[]{Color.GREEN, Color.GREEN, Color.WHITE, Color.WHITE},
new float[]{0,0.5f,.55f,1}, Shader.TileMode.REPEAT);
return lg;
}
};
PaintDrawable p=new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
use
Button btn= (Button)findViewById(R.id.btn);
btn.setBackgroundDrawable((Drawable)p);
Try this snipet:
ImageView img = (ImageView)findViewById(R.id.backimg);
img.setImageResource(R.drawable.fg_graidient);
I use following java code to run this,
public class MainActivity extends ActionBarActivity {
int transitionTime = 300;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TransitionDrawable transition = (TransitionDrawable) findViewById(R.id.relativeLayoutMain).getBackground();
transition.startTransition(transitionTime);
}
Please help me to sole this problem.
Hi I'm new to android and what I'm try to do is change layout background color continuously.
Above method trigger error to me, I not found solution to this but I use different approach to do this.
I use timer with TransitionDrawable and here is my working copy of code.
Here I add "drawable" resources,
transition_drawable.xml (this is main resource xml set this resource file to your layer backbround)
<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
<item android:drawable="#drawable/color_selector_01" />
<item android:drawable="#drawable/color_selector_02" />
</transition>
color_selector_01.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="90"
android:startColor="#919bfa"
android:endColor="#4e5bda"
android:type="linear" />
</shape>
</item>
</selector>
color_selector_02.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="90"
android:startColor="#fe5528"
android:endColor="#3c1ed4"
android:type="linear" />
</shape>
</item>
</selector>
In my main layout I set layer background to "transition_drawable"
here is my "activity_main.xml"
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:background="#drawable/transition_drawable" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="#+id/linkTerms"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:singleLine="true"
android:text="#string/linkTerms" />
<TextView
android:id="#+id/and"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="#string/and" />
<TextView
android:id="#+id/linkPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:text="#string/linkPrivacy" />
</LinearLayout>
</ScrollView>
Finlay here is my MainActivity.java file
#TargetApi(Build.VERSION_CODES.HONEYCOMB) #SuppressLint("NewApi") public class MainActivity extends ActionBarActivity {
int transitionTime = 6000;
private RelativeLayout Rlayout;
private TransitionDrawable trans;
final Handler handler_interact=new Handler();//not defined as final variable. may cause problem
View layout_interact;
#SuppressLint("NewApi") #Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout_interact =(View) findViewById(R.id.relativeLayoutMain);
Rlayout = (RelativeLayout)findViewById(R.id.relativeLayoutMain);
Resources res = this.getResources();
trans = (TransitionDrawable)res.getDrawable(R.drawable.transition_drawable);
Rlayout.setBackgroundDrawable(trans);
BackgroundColoerChangerCallTimer();
}
public void BackgroundColoerChangerCallTimer(){
//creating timer
Timer timer_interact=new Timer();
timer_interact.schedule(new TimerTask() {
#Override
public void run() {
UpdateGUI();
}
}, 3000);
}
private void UpdateGUI() {
handler_interact.post(runnable_interact);
}
//creating runnable
final Runnable runnable_interact = new Runnable() {
public void run() {
//ayout_interact.setBackgroundColor(Color.GREEN);
trans.reverseTransition(transitionTime);
BackgroundColoerChangerCallTimer();
}
};
I'm trying to draw this shape in my android app :
i want to draw a hollow circle with wide stroke,
i want to draw a hollow circle with wide stroke, and i want that each circle will fill in a custom way. if the user enter 57 then the circle stroke will be 57% yellow and in the middle of the shape will be text view.
is there a way to do it?
this is my code so far:
public class MyView extends View {
Paint paint;
Path path;
public MyView(Context context) {
super(context);
init();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(50, 50, 30, paint);
}
}
and the xml
<?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:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="vertical"
android:padding="10dp" >
<TextView
style="#style/black_textview"
android:text="#string/status_m" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/frame_graph_1"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:orientation="vertical" >
</FrameLayout>
<FrameLayout
android:id="#+id/frame_graph_2"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:orientation="vertical" >
</FrameLayout>
<FrameLayout
android:id="#+id/frame_graph_3"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:orientation="vertical" >
</FrameLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
and this is the main class
public class HomeGraphFragment extends Fragment {
FrameLayout frameGraph1 , frameGraph2 , frameGraph3;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.home_graph, container, false);
init(v);
return v;
}
private void init(View v) {
frameGraph1 = (FrameLayout)v.findViewById(R.id.frame_graph_1);
frameGraph2 = (FrameLayout)v.findViewById(R.id.frame_graph_2);
frameGraph3= (FrameLayout)v.findViewById(R.id.frame_graph_3);
frameGraph1.addView(new MyView(getActivity()));
}
}
You can customize your progress bar:
<item android:id="#android:id/background">
<rotate
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270" >
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="15.0" >
<solid android:color="#color/clr_secondary" />
</shape>
</rotate>
</item>
<item android:id="#android:id/secondaryProgress">
<rotate
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270" >
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="15.0" >
<solid android:color="#color/clr_secondary" />
</shape>
</rotate>
</item>
<item android:id="#android:id/progress">
<rotate
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270" >
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="15.0" >
<solid android:color="#color/clr_primary" />
</shape>
</rotate>
</item>
Finally set ProgressBar drawable to your drawable
android:progressDrawable="#drawable/blue_progress_bar"
To display text in center, set RelativeLayout as background and then add ProgressBar and TextView. Then set centerInParent="true" in your parent RelativeLayout
You can use SweepGradient, passing the your circle center coordinates as parameters.