I am trying to add image to the point (X,Y) on Layout i have created dynamicaly.
I want to add the imageview on exact user clicked location. But the image is not placed on correct location when clicked.
here is my code
final LinearLayout layoutColumnBoxes = new LinearLayout(getParent());
layoutColumnBoxes.setBackgroundColor(Color.GREEN);
layoutColumnBoxes.setId(counterIdForBoxes);
layoutColumnBoxes.setLayoutParams(layoutParamsColumns);
layoutColumnBoxes.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Toast.makeText(getParent(),"Event="+event.getX()+"Event Y = "+event.getY(),Toast.LENGTH_SHORT).show();
return false;
}
});
layoutColumnBoxes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView imageView = new ImageView(getParent());
imageView.setImageResource(R.drawable.crack);
LinearLayout lay = (LinearLayout) view.findViewById(v.getId());
lay.addView(imageView);
// Toast.makeText(getParent(),"Clicked View Id is="+v.getId(),Toast.LENGTH_SHORT).show();
}
});
Please help.
See I know what you're trying to say cause I too had this problem a few months back when developing an application. When you click a point on the screen the position of the imageview is not close to the way you clicked it right?
the things I did were
1) remove the excess space around your image.
This is optional. The only reason I stated this was because it depends on the type of image in your image view cause later you will be placing the image based on the top left corner of the imageview.
2) if your loading the images from the drawable folder make sure that you have the right size image in the right folder. This is IMPORTANT. if you screw up the sizes, android is going to alter the size and location of your images based on when your touch is based on the screen.
3) you need to set the margins of your image view properly. After hours of googling I came up with the following first you'll need to get half the height and width of your imageview, use imageview.getMeasuredHeight() / 2 and imageview.getMeasuredWidth() / 2 (Call these imgH and imgW respectively for explanation purposes)
the later in your OnTouchListener you'll have to set the top left margin of your imageview (the methods vary on the type of layout you use). This is done by setting the top margin at "event.getY - imgH" and the left margin at "event.getX - imgW"
I have an app in the playstore which uses this feature, you can check it here .
I hope this has solved your problem :) if it hasn't then don't hesitate to speak your doubts.
this code work for me:
public class MainActivity extends ActionBarActivity {
float x, y;
RelativeLayout rl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getActionBar().hide();
rl = (RelativeLayout) findViewById(R.id.root_view);
rl.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
// rl.removeView(iv);
x = motionEvent.getX();
y = motionEvent.getY();
setImageLocation(x, y);
//rl.addView(iv);
}
return false;
}
});
}
public void setImageLocation(float x, float y) {
ImageView newImage;
RelativeLayout.LayoutParams newparams;
newparams = new RelativeLayout.LayoutParams(20, 20);
newparams.setMargins((int) (x-rl.getPaddingLeft()), (int) (y-rl.getPaddingTop()), 0, 0);
newImage = new ImageView(this);
newImage.setLayoutParams(newparams);
newImage.setImageResource(R.drawable.clock);
rl.addView(newImage);
}
}
activity_main.xml layout only has one relativeLayout that has full screen size(match parent)
Related
I have a RecyclerView in Android Studio with items within it, and instead of swiping horizontally to a new activity, I'd like to swipe left/right, have the entire RecyclerView (or all of its items, either way, since the overall effect would appear similar) move with my finger. Once the items (or RecyclerView) leave the screen at a threshold (for example, 50%), then I'd like to initiate an animation of new items sliding in.
So far, I have the animation for the items sliding in but cannot:
Get all items or the entire RecyclerView to be dragged by by finger
Once that's accomplished, calculate the percentage of the items/view is offscreen to invoke a function.
Thanks in advance
EDIT:
In my main activity, I already have an onTouchListener to register swiping and each of my items are clickable, but I want to be able to "animate" the items moving left offscreen when I swipe left
An example of my code:
public class MainActivity extends AppCompatActivity {
// Set up layout and such...
...
Recyclerview recyclerview = findViewById(R.id.mRecyclerview);
// Set layout manager and adapter...
...
recyclerview.setOnTouchListener(new SwipeListener(MainActivity.this) {
#Override
public void onSwipeRight() {
super.OnSwipeRight();
swipeRightAnimation();
}
#Override
public void onSwipeLeft() {...}
...
});
/* How do I animate items moving left when swiping right and vice versa?
Inside of SwipeListener? By implementing a new listener? */
}
EDIT2:
I tried this (acting on the parent layout instead of the RecyclerView), but the overall view seems to grow/shrink symmetrically rather than move left or right, any suggestions?
public class HorizontalDragListener implements View.OnTouchListener {
private Context context;
private int x;
private int dXLeft;
private int dXRight;
private DrawerLayout.LayoutParams layoutParams;
public HorizontalDragListener(Context context) {
this.context = context;
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// Get position information
x = (int) motionEvent.getRawX();
y = (int) motionEvent.getRawY();
// Detect movements
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case (MotionEvent.ACTION_DOWN): {
layoutParams = (DrawerLayout.LayoutParams) view.getLayoutParams();
dXLeft = x - layoutParams.leftMargin;
dXRight = layoutParams.rightMargin - x;
break;
}
case (MotionEvent.ACTION_MOVE): {
// move object
layoutParams = (DrawerLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = x - dXLeft;
layoutParams.rightMargin = x + dXRight;
view.setLayoutParams(layoutParams);
break;
}
}
// Update view
view.invalidate();
return true;
}
}
So, I need to get coordinates of my touch on ImageView.
I have already successfully tried to get coordinates in OnTouchListener event. But it is not what i really need.
The problem is that the resolution of the screen is much lower than the resolution of the picture in ImageView.
How to get actual coordinates (maybe certain pixels) of the image?
Android: How do I get the x y coordinates within an image / ImageView?
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
int[] values = new int[2];
view.getLocationOnScreen(values);
Log.d("X & Y",values[0]+" "+values[1]);
}
});
Something like this?
There's getLocationOnScreen() and getLocationInWindow() methods for the purpose.
imageView.setOnTouchListener(new OnTouchListener() {
#Override public boolean onTouch(View view, MotionEvent motionEvent) {
int[] locations = new int[2];
view.getLocationOnScreen(locations);
//view.getLocationInWindow(locations);
return false;
}
});
I have an idea for implementing of a login with password as the image touch positions when the member touch the same position I have to login the user.Can anyone help me how to implement it I can get the position of screen only. and the x and y coordinated are changing even when I touch the same position.
I would say create a custom View that extends ImageView:
public class PasswordView extends ImageView {
public PasswordView(Context context) {
super(context);
// Any additional PasswordView setup
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float xTouchPos = event.getX();
float yTouchPos = event.getY();
// If the PasswordView was clicked
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Check if they touched in the secret spot
}
return super.onTouchEvent(event);
}
}
By subclassing ImageView, you will still have access to all the standard features of an ImageView (setting an image source, etc.) and you will also be able to add the additional functionality for checking a user's touch position.
Here's an example project that uses onTouchEvent.
I'm writing a simple app that implements a material design compliant nav drawer as described by this Stack post: https://stackoverflow.com/a/27153313/1621380
The ScrimInsetsFrameLayout works great and everything is dandy until I attempt to programmatically change the color of the status bar. My app uses the Palette API to change the toolbar and status bar color dynamically.
I'm using the property animation api to animate the toolbar and it works great! but I try to do the same animation on the statusbar and it doesn't seem to want to animate. Here's an example
Here is the code for my animator:
public static void fadeStatusBar(final DrawerLayout layout, Integer from, Integer to) {
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animator) {
layout.setStatusBarBackgroundColor((Integer) animator.getAnimatedValue());
}
});
colorAnimation.start();
}
}
Note: That same code is fading the toolbar, so its proven to work.
My question is; does anyone know of a way to get a smooth transition when using DrawerLayout.setStatusBarBackgorundColour()?
Note: I have used the Window method window.setStatusBarColor() method, and it animates fine but breaks the "transparent statusbar" when the NavDrawer is pulled in.
As advised #adneal's comment on my original question the answer was to invalidate the view during the animation.
DrawerLayout calculates the top inset and draws the status bar background itself. So, you just need to make a call to View.invalidate to force it to redraw while the animation is being updated. #adneal
I've updated my code to this
ValueAnimator colorAnimation = ValueAnimator.ofArgb(from, to);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animator) {
layout.invalidate();
layout.setStatusBarBackgroundColor((Integer) animator.getAnimatedValue());
}
});
colorAnimation.start();
For anyone wondering why this worked, I found this stack post enlightening: When it's necessary to execute invalidate() on a View?
you can do this Easily like below:
1 - set your statusbar color to transparent by using this:
<item name="colorPrimaryDark">#android:color/transparent</item>
2 - define application's view to change it background:
View root = *A_view_on_the_activity*.getRootView();
3 - then add this function to your project:
private void color_change(final View view,int from_color,int to_color){
final float[] from = new float[3],
to = new float[3];
String hexColor_from = String.format("#%06X", (0xFFFFFF & from_color));
String hexColor_to = String.format("#%06X", (0xFFFFFF & to_color));
Color.colorToHSV(Color.parseColor(hexColor_from), from); // from
Color.colorToHSV(Color.parseColor(hexColor_to), to); // to
ValueAnimator anim = ValueAnimator.ofFloat(0, 1); // animate from 0 to 1
anim.setDuration(600); // for 300 ms
final float[] hsv = new float[3]; // transition color
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
#Override public void onAnimationUpdate(ValueAnimator animation) {
// Transition along each axis of HSV (hue, saturation, value)
hsv[0] = from[0] + (to[0] - from[0])*animation.getAnimatedFraction();
hsv[1] = from[1] + (to[1] - from[1])*animation.getAnimatedFraction();
hsv[2] = from[2] + (to[2] - from[2])*animation.getAnimatedFraction();
view.setBackgroundColor(Color.HSVToColor(hsv));
}
});
anim.start();
}
4 - and then change the hole application's background color animation by using the function that Written above:
color_change(root, from_color, to_color);
I am creating an image by using Canvas- and Bitmap class. I want to set it as a background for the user. Then I want to add some more images on top of it.
this is the code for image that is supposed to be as background.
ImageView imgMap1 = (ImageView) findViewById(R.id.imgMap1);
imgMap1.setImageDrawable(new BitmapDrawable(Bitmap.createBitmap(bmp, 0, 0, 500, 500)));
and this is the code to make it as background:
LinearLayout ll = new LinearLayout(this);
ll.setBackgroundResource(R.drawable.nn);
this.setContentView(ll);
The Problem here is: When I set it as background, I can't see the other photo anymore.
How can I do this?
Thanks in advance.
The other Images are added in the Layout. they are movable by finger touch. user can reposition them by finger.
ImageView i1 = (ImageView) findViewById(R.id.Image1);
ImageView i2 = (ImageView) findViewById(R.id.Image2);
The layout is built from the top down in your XML file, or in the order you add elements in code. It sounds like your other images is being added to the layout first, either as a higher-up element in the XML file, or earlier in your code. You'll need to add the other code as context for a complete answer.
Just noticed that you can directly set Bitmap as your ImageView's content using setImageBitmap(Bitmap bm)See the Android Reference
Then let talk about your question.
First, create your own class extends the View;
Second, load background image and overlay image using Bitmap
Third, invoke onTouch event, so that the onDraw method will automatically redraw the overlay image using the coordinates returned by onTouch
Something like:
public class dragndrop extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// using this to load your background image
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565; // this is not a must
bmBackground = BitmapFactory.decodeFile(filePath, opt);
super.onCreate(savedInstanceState);
DrawView dv = new DrawView(dragndrop.this);
setContentView(dv);
}
public class DrawView extends View {
Point coordinate;
public DrawView(Context context) {
super(context);
setFocusable(true); //necessary for getting the touch events
}
#Override
protected void onDraw(Canvas canvas) {
// assume you have already load your background image as bitmap
canvas.drawBitmap(bmBackground, 0, 0, null);
// assume bm is the overlay image you need to put on top,
// the method here will draw the object with the coordinate you give
canvas.drawBitmap(bm, coordinate.x, coordinate.y, null);
}
// events when touching the screen
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int x = (int)event.getX();
int y = (int)event.getY();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
// add code here to determine the point user touched is within the object or not
break;
}
}
break;
case MotionEvent.ACTION_MOVE: // touch 'n' drag
// pass the touch point to your object
coordinate.x = x;
coordinate.y = y;
break;
case MotionEvent.ACTION_UP:
// touch drop - just do things here after dropping
break;
}
// redraw the canvas
invalidate();
return true;
}
}
}
This is my own snippet, please edit before use, and please let me know when your question is resolved.