Not able to add custom view into the layout programmatically - android

Hi I am creating a custom view in android.I have a LinerarLayout to which I am adding the custom views.I manage to add one custom view programmatically but if I add another it's not getting added into the layout.I don't know where am going wrong.My Main activity.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout container = (LinearLayout) findViewById(R.id.container);
final MyAnimationView animView = new MyAnimationView(this);
container.addView(animView);
final MyAnimationView animView1 = new MyAnimationView(this);
container.addView(animView1);
}
and my custom view class
public class MyAnimationView extends TextView implements ValueAnimator.AnimatorUpdateListener {
public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
AnimatorSet animation = null;
private float mDensity;
public MyAnimationView(Context context) {
super(context);
mDensity = getContext().getResources().getDisplayMetrics().density;
ShapeHolder ball0 = addBall(75f, 400f);
}
public MyAnimationView(Context context,float x,float y) {
super(context);
mDensity = getContext().getResources().getDisplayMetrics().density;
ShapeHolder ball0 = addBall(105f, 400f);
}
private void createAnimation() {
if (animation == null) {
ObjectAnimator anim0=ObjectAnimator.ofFloat(balls.get(0),"y",getHeight(),500f).setDuration(500);
animation = new AnimatorSet();
animation.playTogether(anim0);
anim0.addUpdateListener(this);
}
}
private ShapeHolder addBall(float x, float y) {
OvalShape circle = new OvalShape();
circle.resize(100f * mDensity, 100f * mDensity);
ShapeDrawable drawable = new ShapeDrawable(circle);
ShapeHolder shapeHolder = new ShapeHolder(drawable);
shapeHolder.setX(x - 25f);
shapeHolder.setY(y - 25f);
int red = (int)(100 + Math.random() * 155);
int green = (int)(100 + Math.random() * 155);
int blue = (int)(100 + Math.random() * 155);
int color = 0xff000000 | red << 16 | green << 8 | blue;
Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
50f, color, darkColor, Shader.TileMode.CLAMP);
paint.setShader(gradient);
shapeHolder.setPaint(paint);
balls.add(shapeHolder);
return shapeHolder;
}
#Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < balls.size(); ++i) {
ShapeHolder shapeHolder = balls.get(i);
canvas.save();
canvas.translate(shapeHolder.getX(), shapeHolder.getY());
shapeHolder.getShape().draw(canvas);
canvas.restore();
}
}
public void startAnimation() {
createAnimation();
animation.start();
}
public void onAnimationUpdate(ValueAnimator animation) {
invalidate();
}
}
EDIT:here is my linear layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="#+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
any help will be greatly appreciated.

Just an assumption, donĀ“t know if it works. Try to do this in Your main:
LinearLayout container = (LinearLayout) findViewById(R.id.container);
final MyAnimationView animView = new MyAnimationView(this);
animView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.
WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
container.addView(animView);
final MyAnimationView animView1 = new MyAnimationView(this);
animView1.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.
WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
container.addView(animView1);
does it work?

No it will be added but you can't see it. because your first view will take the full space of your screen. And your second will be added in below of your first view so it will be hidden from visible part of your device. I also met the same problem. I solved this with two layouts. see here for my solution.
I assume this is the problem that is why I provided this solution if not kindly let me know..

Related

Adding graphics views android layout

This will be my first question, so I apologize for my probable mistakes.
I'm trying to add a red circle each time I press the button I've incorported to my layout. I'd like all circles stayed in the layout:
<?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" >
<LinearLayout
android:id="#+id/panelJuego"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.76"
android:orientation="horizontal" >
</LinearLayout>
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="botonRojo"
android:text="Button" />
</LinearLayout>
The java code related with my trying is:
public void botonRojo(View v) {
LinearLayout panelJuego = (LinearLayout) findViewById(R.id.panelJuego);
PonCirculo circulo = new PonCirculo(this, 30, 30, "#FF0000");
circulo.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
panelJuego.addView(circulo);
}
public class PonCirculo extends View {
private int radio = 30;
private String color;
public PonCirculo(Context context, int x, int y, String color) {
super(context);
Cx = Cx + x;
Cy = Cy + y;
this.color = color;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor(color));
canvas.drawCircle(Cx, Cy, radio, paint);
}
Actually each time I press the button a red filled circle appears in the android screen but when I press the button again a new circle appears and the fomer disappears. Can anyone help me? Thanks.
I'm assuming you are just trying to add each circle under each other when the button is pressed.
Currently you are adding a new view each time now but it is over-laying the previous view. You need add the views giving each new circle a unique id. Then place the new circle underneath or whatever position you choose. I'm giving you some example code that I changed to use a relative layout and I place each circle under the previous one. This should get you started with what you are looking for:
Example Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/relativeCircleLayout">
</RelativeLayout>
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Circle"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:onClick="botonRojo"/>
</RelativeLayout>
Example Code:
public class MainActivity extends AppCompatActivity {
ArrayList<PonCirculo> viewList = new ArrayList<PonCirculo>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void botonRojo(View v) {
RelativeLayout panelJuego = (RelativeLayout) findViewById(R.id.relativeCircleLayout);
PonCirculo circulo = new PonCirculo(this, 30, 30, "#FF0000");
circulo.setId(View.generateViewId());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 100);
if(!viewList.isEmpty()) {
int id = viewList.get(viewList.size()-1).getId();
params.addRule(RelativeLayout.BELOW, id);
}
panelJuego.addView(circulo, params);
viewList.add(circulo);
}
public class PonCirculo extends View {
private int radio = 30;
private String color;
int Cx, Cy;
public PonCirculo(Context context, int x, int y, String color) {
super(context);
Cx = Cx + x;
Cy = Cy + y;
this.color = color;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor(color));
canvas.drawCircle(Cx, Cy, radio, paint);
}
}
}

create vertical lines in seekbar

I'm trying to create something like this. The problem is how to create vertical lines close to the seekbar. I tried the code given here, but the seekbar line disappears. Any help would be appreciated. Here is what I've done so far.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SeekBar sb = (SeekBar)findViewById(R.id.seekBar1);
//Get the width of the main view.
Display display = getWindowManager().getDefaultDisplay();
Point displaysize = new Point();
display.getSize(displaysize);
int width = displaysize.x;
//set the seekbar maximum (Must be a even number, having a remainder will cause undersirable results)
//this variable will also determine the number of points on the scale.
int seekbarmax = 10;
int seekbarpoints = (width/seekbarmax); //this will determine how many points on the scale there should be on the seekbar
//find the seekbar in the view, and set some behaviour properties
SeekBar seekbar = (SeekBar)findViewById(R.id.seekBar1);
//Set the seekbar to a max range of 10
seekbar.setMax(seekbarmax);
//Create a new bitmap that is the width of the screen
Bitmap bitmap = Bitmap.createBitmap(width, 100, Bitmap.Config.ARGB_8888);
//A new canvas to draw on.
Canvas canvas = new Canvas(bitmap);
//a new style of painting - colour and stoke thickness.
Paint paint = new Paint();
paint.setColor(Color.BLUE); //Set the colour to red
paint.setStyle(Paint.Style.STROKE); //set the style
paint.setStrokeWidth(1); //Stoke width
Paint textpaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textpaint.setColor(Color.rgb(61, 61, 61));// text color RGB
textpaint.setTextSize(28);// text size
int point = 0; //initiate the point variable
//Start a for loop that will loop seekbarpoints number of times.
for (int i = 0; i < seekbarpoints; i++ ){
if ((i%2)==0) {
//short line
point = point + seekbarpoints;
canvas.drawLine(point, 30, point, 0, paint);
//drawLine(startx,startx,endy,endy)
}
//Create a new Drawable
Drawable d = new BitmapDrawable(getResources(),bitmap);
//Set the seekbar widgets background to the above drawable.
seekbar.setProgressDrawable(d);
}
}
}
I was searching for the this for long time and only got an answer to draw the numbers. Thus I decided to do it myself. I took the solution having only the steps and extended it by adding the logic for the intervals.
Please see the below image.
I then successfully created a seekbar with interval lables and vertical lines over seekbar. The above image is what I've achieved.
However there are few optimization in the padding which you can work on adjusting the dimensions.
Solution :
The xml file for the intervals:
seekbar_with_intervals_labels
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textViewInterval"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#707070"/>
XML for the Vertical deviders : seekbar_vertical_lines
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textViewVerticalLine"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#drawable/lines" />
Then the custom Seekbar class :
package com.example.abc.myapplication;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import com.example.abc.myapplication.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class SeekbarWithIntervals extends LinearLayout {
private RelativeLayout RelativeLayout = null;
private SeekBar Seekbar = null;
private RelativeLayout Divider = null;
private View verticalLine = null;
private int WidthMeasureSpec = 0;
private int HeightMeasureSpec = 0;
public SeekbarWithIntervals(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
getActivity().getLayoutInflater()
.inflate(R.layout.seekbar_with_intervals, this);
}
private Activity getActivity() {
return (Activity) getContext();
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
verticalLine = new View(getActivity());
verticalLine.setLayoutParams(new LayoutParams(2, LayoutParams.MATCH_PARENT));
verticalLine.setBackgroundColor(Color.BLACK);
if (changed) {
alignIntervals();
// We've changed the intervals layout, we need to refresh.
RelativeLayout.measure(WidthMeasureSpec, HeightMeasureSpec);
RelativeLayout.layout(RelativeLayout.getLeft(), RelativeLayout.getTop(), RelativeLayout.getRight(), RelativeLayout.getBottom());
}
}
private void alignIntervals() {
int widthOfSeekbarThumb = getSeekbarThumbWidth();
int thumbOffset = widthOfSeekbarThumb / 2;
int widthOfSeekbar = getSeekbar().getWidth();
int firstIntervalWidth = getRelativeLayout().getChildAt(0).getWidth();
int remainingPaddableWidth = widthOfSeekbar - firstIntervalWidth - widthOfSeekbarThumb;
int numberOfIntervals = getSeekbar().getMax();
int maximumWidthOfEachInterval = remainingPaddableWidth / numberOfIntervals;
alignFirstInterval(thumbOffset);
alignIntervalsInBetween(maximumWidthOfEachInterval);
alignLastInterval(thumbOffset, maximumWidthOfEachInterval);
}
private int getSeekbarThumbWidth() {
return getResources().getDimensionPixelOffset(R.dimen.seekbar_thumb_width);
}
private void alignFirstInterval(int offset) {
TextView firstInterval = (TextView) getRelativeLayout().getChildAt(0);
firstInterval.setPadding(offset - 10, 0, 0, 0);
TextView firstLine = (TextView) getDivider().getChildAt(0);
firstLine.setPadding(offset + 10, 0, 0, 0);
}
private void alignIntervalsInBetween(int maximumWidthOfEachInterval) {
int widthOfPreviousIntervalsText = 0;
int widthOfPreviousLine = 0;
// Don't align the first or last interval.
for (int index = 1; index < (getRelativeLayout().getChildCount() - 1); index++) {
TextView textViewInterval = (TextView) getRelativeLayout().getChildAt(index);
int widthOfText = textViewInterval.getWidth();
// This works out how much left padding is needed to center the current interval.
//int leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 2) - (widthOfPreviousIntervalsText / 2) - (widthOfText / 2));
int leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 2) - (widthOfPreviousIntervalsText / 2) - (widthOfText / index ) + index + 5 * 5);
textViewInterval.setPadding(leftPadding, 0, 0, 0);
widthOfPreviousIntervalsText = widthOfText;
TextView textViewLine = (TextView) getDivider().getChildAt(index);
int widthOfLine = textViewLine.getWidth();
// This works out how much left padding is needed to center the current interval.
leftPadding = (maximumWidthOfEachInterval + (index + (maximumWidthOfEachInterval / 10)) - (index * 4)); //Math.round(maximumWidthOfEachInterval + (widthOfLine ) + (widthOfPreviousLine ));
//leftPadding = Math.round((maximumWidthOfEachInterval - (widthOfPreviousLine / index) - (widthOfPreviousLine / index) - (widthOfPreviousLine / index)) + 10);
textViewLine.setPadding(leftPadding , 0, 0, 0);
widthOfPreviousLine = widthOfLine;
}
}
private void alignLastInterval(int offset, int maximumWidthOfEachInterval) {
int lastIndex = getRelativeLayout().getChildCount() - 1;
TextView lastInterval = (TextView) getRelativeLayout().getChildAt(lastIndex);
int widthOfText = lastInterval.getWidth();
int leftPadding = Math.round(maximumWidthOfEachInterval - widthOfText - offset);
lastInterval.setPadding(leftPadding + 20, 0, 0, 0);
TextView lastLine = (TextView) getDivider().getChildAt(lastIndex);
leftPadding = Math.round(maximumWidthOfEachInterval - (widthOfText / 5) - (widthOfText / 5) - (widthOfText / 5 ) + 3 * 10);
lastLine.setPadding(leftPadding , 0, 0, 0);
}
protected synchronized void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
WidthMeasureSpec = widthMeasureSpec;
HeightMeasureSpec = heightMeasureSpec;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public int getProgress() {
return getSeekbar().getProgress();
}
public void setProgress(int progress) {
getSeekbar().setProgress(progress);
}
public void setIntervals(List<String> intervals) {
displayIntervals(intervals);
getSeekbar().setMax(intervals.size() - 1);
}
private void displayIntervals(List<String> intervals) {
int idOfPreviousInterval = 0;
int idOfPreviousLine = 0;
if (getRelativeLayout().getChildCount() == 0) {
for (String interval : intervals) {
TextView textViewInterval = createInterval(interval);
alignTextViewToRightOfPreviousInterval(textViewInterval, idOfPreviousInterval);
TextView textViewVerticaLine = createVerticalLine();
alignTextViewToRightOfPreviousInterval(textViewVerticaLine, idOfPreviousLine);
idOfPreviousLine = textViewVerticaLine.getId();
idOfPreviousInterval = textViewInterval.getId();
getRelativeLayout().addView(textViewInterval);
getDivider().addView(textViewVerticaLine);
}
}
}
private TextView createInterval(String interval) {
View textBoxView = (View) LayoutInflater.from(getContext())
.inflate(R.layout.seekbar_with_intervals_labels, null);
TextView textView = (TextView) textBoxView
.findViewById(R.id.textViewInterval);
textView.setId(View.generateViewId());
textView.setText(interval);
return textView;
}
private TextView createVerticalLine() {
View textBoxView = (View) LayoutInflater.from(getContext())
.inflate(R.layout.seekbar_vertical_lines, null);
TextView textView = (TextView) textBoxView
.findViewById(R.id.textViewVerticalLine);
textView.setId(View.generateViewId());
return textView;
}
private void alignTextViewToRightOfPreviousInterval(TextView textView, int idOfPreviousInterval) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (idOfPreviousInterval > 0) {
params.addRule(RelativeLayout.RIGHT_OF, idOfPreviousInterval);
}
textView.setLayoutParams(params);
}
public void setOnSeekBarChangeListener(OnSeekBarChangeListener onSeekBarChangeListener) {
getSeekbar().setOnSeekBarChangeListener(onSeekBarChangeListener);
}
private RelativeLayout getRelativeLayout() {
if (RelativeLayout == null) {
RelativeLayout = (RelativeLayout) findViewById(R.id.intervals);
}
return RelativeLayout;
}
private SeekBar getSeekbar() {
if (Seekbar == null) {
Seekbar = (SeekBar) findViewById(R.id.seekbar);
}
return Seekbar;
}
private RelativeLayout getDivider() {
if (Divider == null) {
Divider = (RelativeLayout) findViewById(R.id.fl_divider);
}
return Divider;
}
}
Then the MainActivity where we dynamically add the intervals.
public class MainActivity extends AppCompatActivity {
private SeekbarWithIntervals SeekbarWithIntervals = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<String> seekbarIntervals = getIntervals();
getSeekbarWithIntervals().setIntervals(seekbarIntervals);
}
private List<String> getIntervals() {
return new ArrayList<String>() {{
add("45");
add("55");
add("65");
add("75");
add("85");
add("95");
}};
}
private SeekbarWithIntervals getSeekbarWithIntervals() {
if (SeekbarWithIntervals == null) {
SeekbarWithIntervals = (SeekbarWithIntervals) findViewById(R.id.seekbarWithIntervals);
}
return SeekbarWithIntervals;
}
}
You can put the padding bottom of the divider so as to push it upwards like in your image.
Note : You can also have a single layout defining the divider and the number layout.
You will need two PNG drawables one for background and one for progress.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#android:id/background"
android:drawable="#drawable/seekbar_drawable_frost" />
<item
android:id="#android:id/progress"
android:drawable="#drawable/seekbar_drawable_frost_progress" />
</layer-list>

Circular reveal transition for new activity

As per https://developer.android.com/training/material/animations.html
The ViewAnimationUtils.createCircularReveal() method enables you to
animate a clipping circle to reveal or hide a view.
To reveal a previously invisible view using this effect:
// previously invisible view
View myView = findViewById(R.id.my_view);
// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;
// get the final radius for the clipping circle
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
// make the view visible and start the animation
myView.setVisibility(View.VISIBLE);
anim.start();
This is meant to reveal a view. How can I use this to circularly reveal an entire activity, without any shared elements?
Specifically, I'd like my searchActivity to circularly reveal from the search action button in the toolbar.
After looking for a solution for half a day without a result, I came up with an own implementation. I'm using a transparent activity with a matching root layout.
The root layout is a view which can then be revealed with createCircularReveal().
My code looks like this:
Theme Definition in styles.xml
<style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
Activity Definition in AndroidManifest.xml
<activity
android:name=".ui.CircularRevealActivity"
android:theme="#style/Theme.Transparent"
android:launchMode="singleTask"
/>
then I declared a layout for my activity (I've chosen DrawerLayout, so that I can have a NavDrawer. Every layout should work here.)
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/honey_melon"
>
<!-- Insert your actual layout here -->
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
Important is the FrameLayout with the id root_layout. This view will be revealed in the activity.
Finally I implemented CircularRevealActivity and overwrote onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.do_not_move, R.anim.do_not_move);
setContentView(R.layout.activity_reveal_circular);
if (savedInstanceState == null) {
rootLayout.setVisibility(View.INVISIBLE);
ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
circularRevealActivity();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});
}
}
}
It was important to put circularRevealActivity() into a OnGlobalLayoutListener, because the view needs to be drawn for the animation.
circularRevealActivity() looks like Ishaan's proposal:
private void circularRevealActivity() {
int cx = rootLayout.getWidth() / 2;
int cy = rootLayout.getHeight() / 2;
float finalRadius = Math.max(rootLayout.getWidth(), rootLayout.getHeight());
// create the animator for this view (the start radius is zero)
Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, 0, finalRadius);
circularReveal.setDuration(1000);
// make the view visible and start the animation
rootLayout.setVisibility(View.VISIBLE);
circularReveal.start();
}
Edit 1
The definition for R.anim.do_not_move was added. However, it should work without that line too, if your design does not specify default transitions for activities. Let me know
R.anim.do_not_move:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="0"
android:duration="#android:integer/config_mediumAnimTime"
/>
</set>
If you want to reverse the circular reveal on leaving activity, use the following modification to onBackPressed().
#Override
public void onBackPressed() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int cx = rootLayout.getWidth();
int cy = 0;
float finalRadius = Math.max(rootLayout.getWidth(), rootLayout.getHeight());
Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, finalRadius, 0);
circularReveal.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationEnd(Animator animator) {
rootLayout.setVisibility(View.INVISIBLE);
finish();
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
circularReveal.setDuration(400);
circularReveal.start();
}else{
super.onBackPressed();
}
}
I think you can use ActivityOptionsCompat.makeClipRevealAnimation .
[https://developer.android.com/reference/android/support/v4/app/ActivityOptionsCompat.html#makeClipRevealAnimation(android.view.View, int, int, int, int)](https://developer.android.com/reference/android/support/v4/app/ActivityOptionsCompat.html#makeClipRevealAnimation(android.view.View, int, int, int, int))
To reverse the CircularReveal animation swap the startRadius and endRadius arguments. Also you will need to setup an AnimatorListenerand in the onAnimationEnd() callback method is where you can call finishAfterTransition(). This is for when you press the up navigation or click on the back button.
ou have to draw the circle view, and after that you should create an animation to it.
Creating the circle view:
public class Circle extends View {
private static final int START_ANGLE_POINT = 90;
private final Paint paint;
private final RectF rect;
private float angle;
public Circle(Context context, AttributeSet attrs) {
super(context, attrs);
final int strokeWidth = 40;
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(strokeWidth);
//Circle color
paint.setColor(Color.RED);
//size 200x200 example
rect = new RectF(strokeWidth, strokeWidth, 200 + strokeWidth, 200 + strokeWidth);
//Initial Angle (optional, it can be zero)
angle = 120;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(rect, START_ANGLE_POINT, angle, false, paint);
}
public float getAngle() {
return angle;
}
public void setAngle(float angle) {
this.angle = angle;
}
}
Creating the animation class to set the new angle:
public class CircleAngleAnimation extends Animation {
private Circle circle;
private float oldAngle;
private float newAngle;
public CircleAngleAnimation(Circle circle, int newAngle) {
this.oldAngle = circle.getAngle();
this.newAngle = newAngle;
this.circle = circle;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation transformation) {
float angle = oldAngle + ((newAngle - oldAngle) * interpolatedTime);
circle.setAngle(angle);
circle.requestLayout();
}
}
Put circle into your layout:
<com.package.Circle
android:id="#+id/circle"
android:layout_width="300dp"
android:layout_height="300dp" />
And finally starting the animation:
Circle circle = (Circle) findViewById(R.id.circle);
CircleAngleAnimation animation = new CircleAngleAnimation(circle, 240);
animation.setDuration(1000);
circle.startAnimation(animation);

Custom Dialog Window

i have to implement a custom dialog that should look like this and should have a special position, like i need to attach it to some component.
Could you be so kind to give me some implementation ideas?
I was thinking about overwriting the existing Android Dialog component but i am not sure i can achieve this functionality just like that.
Any link reference or idea is highly appreciated.
make a class which is subclass of Dialog class and set your custom view by setContentView in it, this will make your code bit cleaner. see the sample over here
How to create a Custom Dialog box in android?
all you need to do is create an XML exactly like you would any other layout and inflate it.
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
//here is where you inflate your XML for the dialog
dialog.setContentView(R.layout.your_dialog_xml);
//now you can grab a reference to any component in your given xml like this
Button exampleButton = (Button) dialog.findViewById(R.id.my_xml_button);
//add any listeners etc.
//display your dialog
dialog.show();
I have had a simmillar requirement , hope this helps. ::
CUSTOM DIALOG CLASS
public class CustomDialogShape extends View {
public int startPointY,startPointX;
public int windowWidth;
public int dialogWidth, dialogHeight;
public int leftTop, rightTop;
public CustomDialogShape(Context context) {
super(context);
}
/**
*
* #param XPos
* #param YPos
* #param windowWidth
* #param dialogHeight
* #param dialogWidth
* Get the Click position, dialog dimension and window width from the parent window
* calculate the co-ordinates to draw the custom dialog shape
*/
public void setDimension(int XPos, int YPos, int windowWidth, int dialogHeight, int dialogWidth) {
this.startPointY = YPos;
this.startPointX = XPos;
this.windowWidth = windowWidth;
this.dialogHeight = dialogHeight;
this.dialogWidth = dialogWidth;
if(startPointX <= (windowWidth/2)) {
//Start Position is on the left half of the Screen
if(startPointX < (dialogWidth/2)) {
//Start position is on the leftmost end.
leftTop = 10;
rightTop = leftTop + dialogWidth;
} else {
leftTop = startPointX - (dialogWidth/2);
rightTop = leftTop + dialogWidth;
}
} else {
int rightSideRemaining = windowWidth - startPointX;
if(rightSideRemaining < (dialogWidth/2)) {
//Start position is on the leftmost end.
rightTop = windowWidth - 10;
leftTop = rightTop - dialogWidth;
} else {
rightTop = startPointX + (dialogWidth/2);
leftTop = rightTop - dialogWidth;
}
}
}
public CustomDialogShape(Context context, AttributeSet at) {
super(context, at);
}
/**
* Fill and Stroke Color
*/
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// custom drawing code here
// remember: y increases from top to bottom
// x increases from left to right
Paint paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawPath(drawCustomShape(startPointX, startPointY, leftTop, rightTop), paint);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(Color.GRAY);
canvas.drawPath(drawCustomShape(startPointX, startPointY, leftTop, rightTop), paint);
}
private Path drawCustomShape(int startPointX, int startPointY, int leftTop, int rightTop) {
Path pathFill = new Path();
pathFill.moveTo(startPointX, startPointY);
pathFill.lineTo(startPointX - 10, startPointY + 10);
pathFill.lineTo(leftTop, startPointY + 10);
pathFill.lineTo(leftTop, startPointY + 10 + dialogHeight);
pathFill.lineTo(rightTop, startPointY + 10 + dialogHeight);
pathFill.lineTo(rightTop, startPointY + 10);
pathFill.lineTo(startPointX + 10, startPointY + 10);
pathFill.lineTo(startPointX, startPointY);
pathFill.close();
return pathFill;
}
MyLAYOUT.XML
<?xml version="1.0" encoding="utf-8"?>
<com.cablevision.optimum2.widget.CustomDialogShape
android:id="#+id/custom_shape"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#android:color/transparent" />
<LinearLayout
android:id="#+id/list_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginLeft="100dip"
android:orientation="vertical" >
<ListView
android:id="#+id/stb_listVals"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="40dip"
android:clickable="false"
android:divider="#AA000000"
android:dividerHeight="7.3dip"
android:focusable="false"
android:scrollbarThumbVertical="#drawable/login_help_thumb"
android:scrollbarTrackVertical="#drawable/login_help_track"
android:scrollbars="vertical" >
</ListView>
</LinearLayout>
</FrameLayout>
IN MY CODE
Rect r = locateView(activity.findViewById(View_where_you_touch));
float touchX= //get the touchx position by calculating through r.leftand r.right);
float touchY=r.bottom;
final Dialog dialog = new Dialog(Ctxt,
android.R.style.Theme_Translucent_NoTitleBar);
dialog.getWindow().
setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
dialog.setContentView(R.layout.MyLAYOUT);
CustomDialogShape custom = (CustomDialogShape) chnSTBDialog
.findViewById(R.id.custom_shape);
custom.setDimension( touchX, touchY, custom_shape_width,
custom_shape_height , totalwindowWidth));
public static Rect locateView(View view) {
Rect loc = new Rect();
int[] location = new int[2];
if (view == null) {
Logging.e(TAG, "locateView", "View not found");
}
In the myLAYOUT XML I had my own list, you can make change to the contents for you needs like it can be linear layouts. Hope this helps
You can construct a custom Dialog like follows:
Dialog mDialog;
mDialog = new Dialog(YourActivityName.this);
mDialog.setContentView(R.layout.checklist_navigatepop);//XML layout file
mDialog.setTitle("Navigation alert");
mDialog.setCancelable(true);
mDialog.show();
Button bt = (Button) mDialog.findViewById(R.id.button3);
Button bt1 = (Button) mDialog.findViewById(R.id.button2);
bt.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
onBackPressed();
mDialog.dismiss();
}
});
Your don't need extends Dialog class.
You need something like this.
public Dialog buildDialog() {
Dialog messageDialog = new Dialog(context, android.R.style.Theme_Translucent);
messageDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// Set your custom layout here.
messageDialog.setContentView(R.layout.dialog_wifi_disabled);
// Don't let the user cancel the dialog.
messageDialog.setCancelable(false);
messageDialog.setCanceledOnTouchOutside(false);
// You can get the views, like this.
TextView textView = (TextView) messageDialog.findViewById(R.id.your_view);
}
More info here

Adding view onto an activity

If I want to add a button in this class so that I can call the onclicklistener, how should I do it?
public class GameView extends View {
Path circle;
Paint cPaint;
Paint tPaint;
String z;
int i = 65, strt, arc, leftx, topy, rightx, bottomy, maxx, maxy;
boolean flag1, flag2, flag3;
double n1, n2;
int n, n3 = 180,n4,n5 = 90;
float f1 = 180, f2 = 90;
Button b1;
Random r = new Random();
RectF oval;
public GameView(Context context) {
super(context);
leftx = 0;
topy = 60;
rightx = 150;
bottomy = 120;
z = String.valueOf(Character.toChars(i));
cPaint = new Paint();
cPaint.setColor(Color.RED);
strt = 45;
arc = 315;
n1 = Math.random() * 600;
Log.d("random", z);
if (flag2 == false)
new DrawThread(this);
// cPaint.setStrokeWidth(2);
tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
tPaint.setColor(Color.BLACK);
float scale = getResources().getDisplayMetrics().scaledDensity;
tPaint.setTextSize(20 * scale);
}
public void onSizeChanged(int w,int h,int oldh,int oldw) {
maxx = oldw;
maxy = oldh;
}
//#Override
protected void onDraw(Canvas canvas) {
// Drawing commands go here
oval = new RectF(leftx,topy,rightx,bottomy);
canvas.drawArc(oval, strt, arc, true, cPaint);
while (i < 90) {
canvas.drawText(String.valueOf(Character.toChars(i)),f1,f2, tPaint);
break;
}
}
}
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
add the above below setContentView
setContentView(R.layout.activity_new_game);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
You need to set the layout using setContentView and then initialize views.
Note you can findViewById of the current view hierarchy set to the activity
Edit:
Example: This is an example. I don't see why it won't work if you do similar as below.
<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=".NewGame"
android:id="#+id/relative_layout"
>
<Button
android:id="#+id/prev_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/next_button"
android:layout_alignBottom="#+id/next_button"
android:layout_centerHorizontal="true"
android:text="stop_label" />
<Button
android:id="#+id/next_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginRight="20dp"
android:layout_toLeftOf="#+id/prev_button"
android:text="start_label" />
<RelativeLayout
android:layout_width="wrap_content"
android:id="#+id/rl"
android:layout_below="#+id/prev_button"
android:layout_height="wrap_content"
>
</RelativeLayout>
</RelativeLayout>
Activity
public class MainActivity extends Activity {
private Button btn1;
private EditText edt1, edt2, edt3, edt4 ,edt5, edt6;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView mv = new MyView(this);
setContentView(R.layout.activity_main);
RelativeLayout layout= (RelativeLayout) findViewById(R.id.rl);
layout.addView(mv);
}
class MyView extends View
{
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawColor(Color.RED);
}
}
}
snapshot
You need to inflate your view before trying to find your relative layout. Try :
RelativeLayout layout;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
gameview=new GameView(this);
setContentView(R.layout.activity_new_game);
layout = (RelativeLayout) findViewById(R.id.relative_layout);
//LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//view = mInflater.inflate(R.layout.activity_new_game, gameview, true);
layout.addView(gameview);
}
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
you can't call findViewById before setContentView. Move
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
after setContentView(R.layout.activity_new_game);
you didn't initialize layout in your code so First initialize layout after setContentView then add view to your layout
RelativeLayout layout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_game);
//Initialize game view
GameView gameview=new GameView(this);
//initialize layout
layout = (RelativeLayout) findViewById(R.id.relative_layout);
//adding game view to layout
layout.addView(gameview);
}
Edit:
initializing like this before setContentView
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
is wrong approach you must initialize views only after setContentView like the above code

Categories

Resources