I am try to implement the vertical slider of image control. The image is inside the ScrollView. When it comes to vertical dragging of ImageView, the top margin of relative layout always provide different reading.
If it is greater than 600 something while dragging down, the background image of the relative layout stretch vertically together with the image position I have dragged.
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:fillViewport="true" >
...
<RelativeLayout
android:id="#+id/relativeLayouyt6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/rTop"
android:background="#drawable/plain" >
<ImageView
android:id="#+id/dragImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow_one"
android:visibility="gone" />
</RelativeLayout>
Would you please tell me how to
get the offset I have scrolled in my scrollview ?
I know it is get touch position minus scrolled position and plus image Y position, how to implement this parameter after finishing dragging ?
How to set relative boundary for imageview inside the relative layout ? is it wiser to take this background image out as the imageview?
If I programmatically repositioning of 6 relativelayouts but coming up to the same width , would it affect the scrolling position and the scollview total Height ? If so , How to calculate the offset Y for the repositioning ?
The below is my code as of February 11:
dragImage.setOnTouchListener(new OnTouchListener(){
//private int _xDelta;
private int _yDelta;
#Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//_yDelta = Y - lParams.topMargin;
mOldY2 = y;
break;
case MotionEvent.ACTION_UP:
mViewPager.setPagingEnabled(true);
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
btn4.setBackgroundResource(R.drawable.fbl02);
final float dy = y - mOldY2;
mNewY2 += dy;
mOldY2 = y;
System.out.println(mNewY2);
while(mNewY2 > 224){
mNewY2 -= 224;
}
while(mNewY2 < 157){
mNewY2 += 157;
}
if(mNewY2 < 157 || mNewY2 > 224)
break;
v.setTranslationY((int)mNewY2);
v.invalidate();
float power = (float) ( 51.5/67 -(0.2/67) * mNewY2) ;
System.out.println(power);
Float roundF = new Float( Math.round(power));
midBandStick = roundF;
btn4.setText(String.valueOf(midBandStick) );
//}
//break;
}
return true;
}
The below is my code :
public static void setRLBelowAnother(RelativeLayout rA , RelativeLayout rB ){
RelativeLayout.LayoutParams rparam4 =
(android.widget.RelativeLayout.LayoutParams) rB.getLayoutParams();
rparam4.addRule(RelativeLayout.BELOW, rA.getId());
rB.setLayoutParams(rparam4);
}
setRLBelowAnother(rTop , r1);
setRLBelowAnother(r1 , r2);
setRLBelowAnother(r2 , r6 );
setRLBelowAnother(r6 , r3 );
setRLBelowAnother(r3 , r4 );
setRLBelowAnother(r4 , r5 );
dragImage.setVisibility(View.VISIBLE);
dragImage.setImageResource(R.drawable.slide_lshort);
dragImage.setX((float) (0.15*screenWidth));
dragImage.setY((float) (0.05*screenHeight));
dragImage.setOnTouchListener(new OnTouchListener(){
//private int _xDelta;
private int _yDelta;
#Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
final int X = (int) event.getX();
final int Y = (int) event.getY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) dragImage
.getLayoutParams();
//_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
mViewPager.setPagingEnabled(true);
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
midStick = 0.2f;
btn4.setBackgroundResource(R.drawable.fbl02);
RelativeLayout.LayoutParams ParamsA = (RelativeLayout.LayoutParams) dragImage
.getLayoutParams();
//ParamsA.leftMargin = X - _xDelta;
ParamsA.topMargin = Y - _yDelta;
//ParamsA.rightMargin = -250;
ParamsA.bottomMargin = -250;
mViewPager.setPagingEnabled(false);
int offYb = 0;
int pos = ParamsA.topMargin + offYb ;
if(pos > -52 && pos < 582 ){
dragImage.setLayoutParams(ParamsA);
System.out.println(ParamsA.topMargin);
float power = (float) (100 + (900/634) * ParamsA.topMargin) ;
Float roundF = new Float( Math.round(power));
midStick = roundF;
btn4.setText(String.valueOf(midStick));
}
break;
}
return true;
}
});
Call the getScrollY() method from the ScrollView to get the Y index (scrolled index)
If I understood (otherwise please correct me) you could get a frame (boundary) between the ImageView and the RelativeLayout adding padding or margin to the ImageView. You just need to call android:padding="" or android:margin=""
The height of the ScrollView will change and also the scrollY if the new added RelativeLayout/ImageView doesn't completely fit on the available space. When you finish adding the new layout you could get the scrollY from the ScrollView and see where the ScrollView has scrolled to.
Can you improve the questions 2, 3 and 4? It's quite confusing.
Related
I want to put marker on image like Google map, with functionality like zooming,scrolling of image,dynamically adding of marker on image and marker drag & drop on image.
Marker can not be move from there position when image gets zoom.
On marker click, dialog will open to show its information
Also, I want the x,y position of marker on image, so that next time I can place marker directly to that position.
Here is my xml :
<ScrollView
android:id="#+id/imageOuterScrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical">
<HorizontalScrollView
android:id="#+id/ImageHorizontalScrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:id="#+id/markerAndLoadedImageView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
android:id="#+id/loadedImageFromServer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
</com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView>
</RelativeLayout>
</HorizontalScrollView>
</ScrollView>
Java code :
private void addNewMarker(#DrawableRes int resid, float xCoordinates, float yCoordinates, String pinID) {
image = new ImageView(getActivity());
image.setBackgroundResource(resid);
markerAndLoadedImageView.addView(image);
image.setX(xCoordinates);
image.setY(yCoordinates);
}
private View.OnTouchListener onTouchListener() {
return new View.OnTouchListener() {
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouch(View view, MotionEvent event) {
mSitePlanImageHorizontalScrollView.requestDisallowInterceptTouchEvent(true);
mSitePlanImageOuterScrollView.requestDisallowInterceptTouchEvent(true);
final int x = (int) event.getRawX();
final int y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams)
view.getLayoutParams();
xDelta = x - lParams.leftMargin;
yDelta = y - lParams.topMargin;
pressStartTime = System.currentTimeMillis();
pressedX = event.getX();
pressedY = event.getY();
break;
case MotionEvent.ACTION_UP:
long pressDuration = System.currentTimeMillis() - pressStartTime;
Utility.printLog("pressDuration", "pressDuration" + pressDuration);
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = x - xDelta;
layoutParams.topMargin = y - yDelta;
layoutParams.rightMargin = 0;
layoutParams.bottomMargin = 0;
view.setLayoutParams(layoutParams);
break;
}
Utility.printLog("POINTS", "POINTS : X:" + String.valueOf(x));
Utility.printLog("POINTS", "POINTS : Y:" + String.valueOf(y));
XPoint = x;
YPoint = y;
mMainParentProjectListLayout.invalidate();
return true;
}
};
}
I have use below library for zooming :
https://github.com/davemorrissey/subsampling-scale-image-view
I am able to put marker on image, but I am not getting exact position of marker on image so that I will put marker to that particular position.
Also, marker click and drag & drop functionality are not smooth as required.
Can anyone help me, thanks in advance.
Sorry for the English :)
I am creating a rectangular box and putting an imageView inside it which can be moved. While doing onMove I noticed that imageView is going out of boundries of it's parent view which I don't want. I want to restrict the imageView within the boundaries of it's parent view. How to do that.
Here is the xml:
<FrameLayout
android:layout_width="400dp"
android:layout_height="400dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:id="#+id/objContainer"
android:background="#android:color/holo_blue_bright" >
<ImageView
android:id="#+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/btn_default" />
</FrameLayout>
</RelativeLayout>
And code to handletouch event:
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
final float x = event.getRawX();
final float y = event.getRawY();
// Remember where we started
mLastTouchX = x;
mLastTouchY = y;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
final float x1 = event.getRawX();
final float y1 = event.getRawY();
// Calculate the distance moved
final float dx = x1 - mLastTouchX;
final float dy = y1 - mLastTouchY;
// Move the object
mPosX += dx;
mPosY += dy;
view.setX(mPosX);
view.setY(mPosY);
// Remember this touch position for the next move event
mLastTouchX = x1;
mLastTouchY = y1;
// Invalidate to request a redraw
root.invalidate();
break;
}
return true;
}}
Inside of your overridden onTouch you need to check if the following move will keep the ImageView inside its container.
In other words you need to check if ImageView's rectangle will stay inside the parent after being moved by dx, dy.
Here's an example:
case MotionEvent.ACTION_MOVE:
...
// Calculate the distance moved
final float dx = x1 - mLastTouchX;
final float dy = y1 - mLastTouchY;
// Make sure we will still be the in parent's container
Rect parent = new Rect(0, 0, root.getWidth(), root.getHeight());
int newLeft = (int) (iv.getX() + dx),
newTop = (int) (iv.getY() + dy),
newRight = newLeft + iv.getWidth(),
newBottom = newTop + iv.getHeight();
if (!parent.contains(newLeft, newTop, newRight, newBottom)) {
Log.e(TAG, String.format("OOB # %d, %d - %d, %d",
newLeft, newTop, newRight, newBottom));
break;
}
...
Note also that you don't need to invalidate the container, as setX/setY invalidates the ImageView itself.
Hi I want to do something like this
When user presses rotate icon, text contained in box should gradually rotate and using scale icon, text should be resized.
Right now I am using this code for moving the textview everywhere on the screen
private int _xDelta;
private int _yDelta;
#Override
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
view.setLayoutParams(layoutParams);
break;
}
elementslayout.invalidate();
return true;
}
It is working fine.
On long press of textview I want to show the layout with rotate and scale icon.
My question is,
How to create this type of layout for textview and do rotate and scale accordingly?
I have seen many codes for rotate and scale using matrix like
http://judepereira.com/blog/multi-touch-in-android-translate-scale-and-rotate/
But don't know how to use it here.
I also want to do the same thing, Rotate,Scale as well as move textview all together. I found a link for text rotation here.
Android Two finger rotation
This works totally fine for the text rotation. You just need to add
txt.setRotation(-angle);
In the onRotation Method. May be that helps you.
how do i create an endless / movable layout, which is endless/movable in all directions?
I want to develop an app to create diagrams, and if the diagram gets too big i want it to be movable in all directions.
I hope its understandable.
with regards
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw);
_root = (ViewGroup) findViewById(R.id.draw);
_view = new ImageView(this);
_view.setImageResource(R.drawable.greenbutton);
BitmapDrawable bd=(BitmapDrawable) this.getResources().getDrawable(R.drawable.greenbutton);
int height=bd.getBitmap().getHeight();
int width=bd.getBitmap().getWidth();
/*MyScrollView myV = new MyScrollView(this);
myV.setLayoutParams(_root.getLayoutParams());*/
RelativeLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(height,width);
_view.setLayoutParams(layoutParams);
_view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
v.setLayoutParams(layoutParams);
break;
}
_root.invalidate();
return true;
}
});
//myV.addView(_view);
_root.addView(_view);
<LinearLayout 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:orientation="horizontal"
tools:context=".Draw">
<RelativeLayout
android:id="#+id/draw"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/layout_grid">
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="5"
android:orientation="vertical">
<GridView
android:id="#+id/mostUsedBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="2"
android:layout_weight="1">
</GridView>
<GridView
android:id="#+id/elementBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="2"
android:layout_weight="1"></GridView>
<GridView
android:id="#+id/relBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="2"
android:layout_weight="1"></GridView>
</LinearLayout>
</LinearLayout>
Create a custom view that scrolls (do it manually) and keep everything in two variables let's say scrollX and scrollY (assume the point at the top left point of the screen). So draw everything on top with an offset of scrollX and scrollY.
Here is some code:
public class MyScrollView extends View
{
private int scrollX, scrollY;
private int pinPointX, pinPointY;
public MyScrollView(Context context)
{
super(context);
//Initialize scroll to look at the top left edge of the "paper"
scrollX = 0;
scrollY = 0;
}
public void onTouchEvent(MotionEvent e)
{
switch (e.getAction())
{
case MotionEvent.ACTION_DOWN:
//Mark touch point
pinPointX = (int) e.getX();
pinPointY = (int) e.getY();
break;
case MotionEvent.ACTION_MOVE:
//Scroll view
scrollX += (int) e.getX() -pinPointX;
scrollY += (int) e.getY() -pinPointY;
//Mark new point
pinPointX = (int) e.getX();
pinPointY = (int) e.getY();
break;
}
}
#Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
//Draw everything here with an offset of scrollX, scrollY
}
}
Sorry I may have made some mistakes (mainly with android's class names) but I wrote the code on the go, if u see any minor mistake make sure to correct it.
Note that this code will allow you to scroll "infinitely" at least as long as scrollX and scrollY remain on their int limits (from -2,147,483,648 to 2,147,483,647) you can keep it like that since nobody will scroll that far, but I'd recommend applying some limits just to make the app more "perfect".
Also I'm not sure but I think this code may have some issue if you scroll to the negative side (leftwards and upwards - when scrollX and/or scrollY are negative) but I may be wrong.
If you want to include more views (like a layout that you ask) make it a ViewGroup but I don't have much experience using that. I showed you a logic to follow it's up to you to attach it to your code as you like.
I had 2 views in an activity. One full screen (View1) and other small (View2), half the size of View1.
I can move View2, over View1 by catching onTouch listeners (ACTION_UP/ACTION_DOWN). But i want to show animation/dragging image of View2 while moving on View1. Any suggestion on how to implement this, will be appreciated.
Currently, for moving the View2 in four corner, i'm setting the Layout params in ACTION_UP.
Code::
public boolean onTouch(View view, MotionEvent motionEvent) {
RelativeLayout.LayoutParams layoutParams =(RelativeLayout.LayoutParams)view.getLayoutParams();
int dx=0,dy=0;
switch (motionEvent.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
int x = (int) motionEvent.getX();
int y = (int) motionEvent.getY();
dx = (int) motionEvent.getRawX() - layoutParams.leftMargin;
dy = (int)motionEvent.getRawY() - layoutParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
layoutParams.leftMargin = (int) ((int) motionEvent.getRawX()-dx);
layoutParams.topMargin = (int) ((int)motionEvent.getRawY()- dy);
view.setLayoutParams(layoutParams);
break;
case MotionEvent.ACTION_UP:
view.setLayoutParams(layoutParams);
break;
}
return true;
}
Use ACTION_MOVE and calculate the offset by checking a pointer's x or y value. After that set weight or height/width parameter of the floating View.