custom drag and drop - android

i am a begginer android develpoer and i am tring to build a small soiltare game.
for dragging the cards i implemented a custom viewgroup which is a "DragContainer" from one of the questions here.
my problem is that when i drag a linear layout. my linear layout holds the cards
with a - margin (to overlap the cards) but when i start the drag the dragged "shadow" is my layout without the margin.
here is an example
this is the start of the activity, the left is a linear layout with two children and also the right
when i start the drag this is what i see
as you can see the dragged "shadow" is bigger(without the - margin)
this is the code for the custom drag container(only the stuff that matters):
public boolean startDragChild(View child, ClipData data,
Object myLocalState, int flags) {
setDragTarget(child);
return child.startDrag(data, new EmptyDragShadowBuilder(child),
myLocalState, flags);
}
private void setDragTarget(View v) {
target = v;
onSetDragTarget(v);
}
/**
* this is similar to the constructor of DragShadowBuilder
*
* #param v
*/
protected void onSetDragTarget(View v) {
}
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mOnDrag && target != null) {
canvas.save();
drawDragShadow(canvas);
canvas.restore();
}
}
protected void drawDragShadow(Canvas canvas) {
int h = target.getHeight();
int w = target.getWidth();
canvas.translate(mDragX - w / 2, mDragY - h / 2);
target.draw(canvas);
}

I guess akon does not require the explanation but I would like to tell to the audience of the question.
The margins inside the LinearLayout should be intact as you would be moving ViewGroup itself, so it's children won't have any issue with it's design,
Code is also available on the Github
public class DragTestTwoActivity extends AppCompatActivity {
private LinearLayout source_linearLayout;
private LinearLayout destination_linearLayout;
private static final String TAG = "DragTestTwoActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drag_test_two);
initializeUI();
}
private void initializeUI() {
source_linearLayout = (LinearLayout) findViewById(R.id.DragTestTwoActivity_Source_LinearLayout);
destination_linearLayout = (LinearLayout) findViewById(R.id.DragTestActivityActivity_Destination_LinearLayout);
// source_linearLayout.setOnDragListener(new MyDragListener());
destination_linearLayout.setOnDragListener(new MyDragListener());
source_linearLayout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(source_linearLayout);
source_linearLayout.startDrag(data, shadowBuilder, source_linearLayout, 0);
return true;
}
});
}
private class MyDragListener implements View.OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
Log.d(TAG, "Drag has started");
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.d(TAG, "Drag has ended");
v.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.d(TAG, "Drag has entered");
break;
case DragEvent.ACTION_DRAG_LOCATION:
Log.d(TAG, "Drag location");
break;
case DragEvent.ACTION_DROP:
Log.d(TAG, "Drag has dropped");
View source_linear_Layout = (LinearLayout) event.getLocalState();
LinearLayout view = (LinearLayout) source_linear_Layout.getParent();
view.removeView(source_linear_Layout); // This will remove the imageView where it was
LinearLayout linearLayout = (LinearLayout) v;
if (v.getId() == R.id.DragTestActivityActivity_Source_LinearLayout) {
Log.d(TAG, "This is a source location");
} else if (v.getId() == R.id.DragTestActivityActivity_Destination_LinearLayout) {
Log.d(TAG, "This is a destination");
}
linearLayout.addView(source_linear_Layout); // this will add the ImageView to the new location where it was dropped.
source_linear_Layout.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_EXITED:
Log.d(TAG, "Drag has exited");
break;
}
return true;
}
}
}
activity_drag_test_two.xml
<?xml version="1.0" encoding="utf-8"?>
<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="vertical"
tools:context="activities.list.first.DragTestTwoActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="4sp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_weight="0.5"
android:background="#ABABAB"
android:orientation="vertical"
android:padding="4dp">
<LinearLayout
android:id="#+id/DragTestTwoActivity_Source_LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/DragTestTwoActivity_imageView"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_margin="4dp"
android:scaleType="centerInside"
android:src="#drawable/gohan" />
<ImageView
android:id="#+id/DragTestTwoActivity_imageView2"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_margin="4dp"
android:scaleType="centerInside"
android:src="#drawable/goku" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/DragTestActivityActivity_Destination_LinearLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_weight="0.5"
android:background="#CACACB"
android:orientation="vertical"
android:padding="4dp">
</LinearLayout>
</LinearLayout>
</LinearLayout>
Output
this is how it would look like...

Of course, you can use standart views for this purpose but it is irrational. It will better to use SurfaceView (or if you know OpenGL GLSurfaceView).

Related

unable to access Clipboard Content from foreground service in Android 10+

I know that we can't access clipboard content from background services in 10+ but there is an application that shows copied text on a floating widget in Android 10+ devices using foreground service here's that app. I want to achieve that functionality somehow! please help me.
My app is working fine in android P and lower devices!
FloatingViewService.java
public class FloatingViewService extends Service implements View.OnClickListener {
private WindowManager wm;
private View floatv;
View collapsed;
View expanded;
CharSequence copiedText;
EditText editText;
public FloatingViewService(){
}
#Override
public void onCreate() {
super.onCreate();
// getting the widget layout from xml using layout inflater
floatv = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget,null);
// setting window manager layout parameters
// set foucus able ,, wrap content, set on lock screen etc...
final WindowManager.LayoutParams wrules = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
// getting window service and adding floating view to it
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(floatv,wrules);
//adding click listener to close button and expanded view
collapsed = floatv.findViewById(R.id.layoutCollapsed);
expanded = floatv.findViewById(R.id.layoutExpanded);
editText = floatv.findViewById(R.id.pastehere);
// adding an touch listener to make drag movement of the floating view
floatv.findViewById(R.id.relativeLayoutParent).setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float touchX;
private float touchY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
initialX = wrules.x;
initialY = wrules.y;
touchX = event.getRawX();
touchY = event.getRawY();
return true;
/*as we implemented OnTouchListener() to the root view, OnClickListner() won’t work. So, to detect clicks we will detect clicks in MotionEvent.ACTION_MOVE in the OnTouchListener() using below code:*/
case MotionEvent.ACTION_UP:
int diffX = (int) (event.getRawX() - touchX);
int diffY = (int) (event.getRawY() - touchY);
if(diffX < 10 && diffY < 10){
if (isViewCollapsed()){
collapsed.setVisibility(View.GONE);
expanded.setVisibility(View.VISIBLE);
wrules.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
wm.updateViewLayout(floatv,wrules);
}else {
collapsed.setVisibility(View.VISIBLE);
expanded.setVisibility(View.GONE);
wrules.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wm.updateViewLayout(floatv,wrules);
}
}
return true;
case MotionEvent.ACTION_MOVE:
// moving the widget across the screen
wrules.x = initialX + (int) (event.getRawX() - touchX);
wrules.y = initialY + (int) (event.getRawY() - touchY);
wm.updateViewLayout(floatv,wrules);
return true;
}
return false;
}
});
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboardManager.addPrimaryClipChangedListener(new ClipboardManager.OnPrimaryClipChangedListener() {
#Override
public void onPrimaryClipChanged() {
copiedText = clipboardManager.getPrimaryClip().getItemAt(0).getText();
if(copiedText != null){
editText.setText(String.valueOf(copiedText));
wm.updateViewLayout(floatv,wrules);
}
Toast.makeText(getBaseContext(), copiedText, Toast.LENGTH_SHORT).show();
}
});
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
if(floatv != null) wm.removeView(floatv);
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.layoutExpanded){
collapsed.setVisibility(View.VISIBLE);
expanded.setVisibility(View.GONE);
}else if(v.getId() == R.id.buttonClose){
stopSelf();
}
}
private boolean isViewCollapsed() {
return floatv == null || floatv.findViewById(R.id.layoutCollapsed).getVisibility() == View.VISIBLE;
}
}
layout_floating_widget.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/relativeLayoutParent"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!-- this is the collapsed layout -->
<RelativeLayout
android:id="#+id/layoutCollapsed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible">
<ImageView
android:id="#+id/collapsed_iv"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginTop="8dp"
android:src="#drawable/ic_baseline_menu_book_24" />
<ImageView
android:id="#+id/buttonClose"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginLeft="50dp"
android:src="#drawable/ic_baseline_close_24"
android:background="#color/teal_200"/>
</RelativeLayout>
<!-- this is the expanded layout -->
<LinearLayout
android:id="#+id/layoutExpanded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#a0c3d7"
android:orientation="horizontal"
android:padding="8dp"
android:visibility="gone">
<ImageView
android:id="#+id/buttonSimplifiedCodingExpanded"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="#drawable/ic_baseline_markunread_24"
tools:ignore="ContentDescription" />
<LinearLayout
android:id="#+id/buttonSimplifiedCoding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp"
android:text="Dictionary"
android:textAlignment="center"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
android:textColor="#ffffff"
android:textStyle="bold" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/pastehere"
android:textAlignment="center"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#ffffff"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</FrameLayout>
see these images
text should appear in editText, working in android 9

Intersecting two images in different Layouts

How it looks
I want to check intersection between ImageView to ImageView2 as LinearLayout slides towards ImageView2.
I used Rect but it is not working, ImageView2 Just passed throught it without getting intersect.
Please help me!!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<ImageView
android:id="#+id/tile"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/tile" />
<LinearLayout
android:id="#+id/l1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<ImageView
android:id="#+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
<ImageView
android:id="#+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
</LinearLayout>
#SuppressLint("NewApi")
public class MainActivity extends Activity {
Rect tileRect = new Rect();
Rect b1Rect = new Rect();
Rect b2Rect = new Rect();
ImageView tile,b1,b2;
RelativeLayout layout;
LinearLayout l1;
final Handler h = new Handler();
Boolean tileRight=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
move();
}
private void init() {
// TODO Auto-generated method stub
b1 = (ImageView)findViewById(R.id.b1);
b2 = (ImageView)findViewById(R.id.b2);
tile = (ImageView)findViewById(R.id.tile);
layout = (RelativeLayout)findViewById(R.id.layout);
l1 = (LinearLayout)findViewById(R.id.l1);
tile.setX(320);
tile.setY(800);
l1.setVisibility(View.VISIBLE);
}
public void move()
{
final int delay = 45;
h.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(tileRight==true)
tileRight=false;
else
tileRight=true;
return true;
}
return false;
}
});
if(tileRight==true)
{
if(tile.getX()>600f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()+speedTile);
}
}
else{
if(tile.getX()<40f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()-speedTile);
}
}
tile.getHitRect(tileRect);
b1.getHitRect(b1Rect);
b2.getHitRect(b2Rect);
if(Rect.intersects(tileRect, b1Rect) || Rect.intersects(tileRect, b2Rect))
{
gameOver();
}
l1.setY(l1.getY()+10f);
h.postDelayed(this, delay);
}
},delay);
}
private void gameOver() {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Android's View has getLocationOnScreen() method that shows absolute position of your view.
https://developer.android.com/reference/android/view/View.html#getLocationOnScreen(int[])
The issue occurs because view.getHitRect() is used before the layouts are inflated.
Any of the view's position or measurement APIs like getWidth(), getTop(), getRight() etc. will return 0 (getHitRect() initializes the Rect with (0,0,0,0)) in onCreate() or onResume() before the views are inflated.
In your case, it appears that the Handler's delay period executes the intersection logic earlier than view inflation.
You could post from the view and the run() method will execute after the view inflates and then obtain the view's measurement parameters or a Rect .
Here is an example:
public class MyTestActivity extends AppCompatActivity{
int mNumberOfViewsInitialized = 0;
ImageView mImageViewRight, mImageViewLeft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_image_activity);
mImageViewLeft = (ImageView) findViewById(R.id.image_view_left);
mImageViewRight = (ImageView) findViewById(R.id.image_view_right);
// calling method here will log that the views do not intersect
// which happens because they haven't been inflated yet.
// doViewsOverlap();
mImageViewLeft.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
mImageViewRight.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
}
private void intersectionLogic(){
/* the constant could be something else, depending
on the number of views you'd like to test intersection for*/
if(mNumberOfViewsInitialized == 2){
doViewsOverlap(mImageViewLeft,mImageViewRight);
}
}
private void doViewsOverlap(final View firstView, final View secondView){
Rect leftRect = new Rect();
firstView.getHitRect(leftRect);
Rect rightRect = new Rect();
secondView.getHitRect(rightRect);
if(Rect.intersects(leftRect,rightRect) || Rect.intersects(rightRect,leftRect))
Log.v("intersects","views intersect");
else
Log.v("intersects","views do not intersect");
}
}
I used a layout which does not animate / move the images, but the same issue should occur when the images are moved as well
<ImageView
android:id="#+id/image_view_left"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:background="#android:color/holo_blue_dark"
android:src = "#mipmap/ic_launcher"/>
<ImageView
android:id="#+id/image_view_right"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentRight="true"
android:background="#android:color/holo_green_dark"
android:gravity="end"
android:src="#mipmap/ic_launcher"/>
Images contained in a RelativeLayout.
Here is a screenshot of the UI:
This problem is related to this: If I call getMeasuredWidth() or getWidth() for layout in onResume they return 0
Hope this helps.

How to enable/disable zooming at runtime?

I am working on images, I am going to display image in full screen, as user touches on screen then some controls will be shown. So I want to disable zooming when controls are on the screen.
Or somebody tell me how to detect the image is zoom or not?
activity_image.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="#+id/imgSelected"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="centerInside"
android:src="#drawable/placeholder"
android:contentDescription="#string/image" />
<LinearLayout
android:id="#+id/imageControls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:weightSum="9"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="horizontal"
android:visibility="gone"
android:background="#drawable/image_controls">
<Button
android:id="#+id/btnSetAsBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:gravity="left|center_vertical"
android:background="#00000000"
style="#style/ImageControls"
android:text="Set"/>
<Button
android:id="#+id/btnFavorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#00000000"
style="#style/ImageControls"
android:text="Favourite"/>
<Button
android:id="#+id/btnShare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:gravity="right|center_vertical"
android:background="#00000000"
style="#style/ImageControls"
android:text="Share"/>
</LinearLayout>
</RelativeLayout>
activity_zoom.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center" >
</LinearLayout>
ImageActivity.java
public class ImageActivity extends Activity {
private int imageId;
private int categoryId;
private String imageUrl;
private ZoomView zoomView;
private ImageView imageView;
private LinearLayout main_container;
private boolean controlFlag;
private LinearLayout imageControls;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zoom);
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
final View convertView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.activity_image, null, false);
convertView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
imageControls = (LinearLayout) convertView.findViewById(R.id.imageControls);
controlFlag = false;
zoomView = new ZoomView(this);
imageId = getIntent().getExtras().getInt("image");
categoryId = getIntent().getExtras().getInt("category");
imageView = (ImageView) convertView.findViewById(R.id.imgSelected);
imageUrl = SplashActivity.urlList.get(categoryId).get(imageId);
Log.e(String.valueOf(categoryId),imageUrl);
Picasso
.with(this)
.load(imageUrl)
.placeholder(R.drawable.placeholder)
.into(imageView, new Callback() {
#Override
public void onError() {
}
#Override
public void onSuccess() {
imageView.setScaleType(ScaleType.FIT_CENTER);
}
});
zoomView.addView(convertView);
main_container = (LinearLayout) findViewById(R.id.main_container);
main_container.addView(zoomView);
convertView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if(controlFlag) {
imageControls.setVisibility(View.GONE);
controlFlag = false;
} else {
imageControls.setVisibility(View.VISIBLE);
controlFlag = true;
}
return false;
}
});
}
}
I am using android-zoom-view.jar library for zooming. I want to display LinearLayout (imageControls) only if image is not zoom Or disable zooming if LinearLayout (imageControls) is visible. Because ZoomView instance perform zooming on all over activity so the imageControls will also be zoom. This is not a good user friendly design.
So please help me to make this layout better.
Thanks...
In zoomview class thinking you using this https://github.com/Polidea/android-zoom-view/blob/master/src/pl/polidea/view/ZoomView.java
just add this
boolean isZoomEnable= true;
public void setIsZoomEnable(boolean value){
isZoomEnable = value;
}
#Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
if(!isZoomEnable) return false;
// single touch
if (ev.getPointerCount() == 1) {
processSingleTouchEvent(ev);
}
// // double touch
if (ev.getPointerCount() == 2) {
processDoubleTouchEvent(ev);
}
// redraw
getRootView().invalidate();
invalidate();
return true;
}
Then in your code
convertView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if(controlFlag) {
imageControls.setVisibility(View.GONE);
controlFlag = false;
} else {
imageControls.setVisibility(View.VISIBLE);
controlFlag = true;
}
zoomView.setIsZoomEnable(!controlFlag);
return false;
}
});

drag and drop auto scroll with multiple layout in android

"auto scroll not working very well when i drag and drop the image with multiple layout"
I searched all over, but could not find a solution.
i got a solution from this link:
Make a scrollView autoscroll with drag and drop in Android
#thehayro thanks for such a nice example.
but it is working for only one layout and auto scroll is also worked. but i have more than 4-5 child layout in one linear layout and this layout is in the scroll view my layout file is like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.dragvdropdemo.MyScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/scroll_view">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/lldrag">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dip"
android:id="#+id/ll1"
android:layout_marginTop="10dip"
android:background="#android:color/darker_gray">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/dr_logo" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/fb" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dip"
android:id="#+id/ll2"
android:layout_marginTop="10dip"
android:background="#android:color/darker_gray">
<ImageView
android:id="#+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/twitter" />
<ImageView
android:id="#+id/ImageView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/ImageView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dip"
android:id="#+id/ll3"
android:layout_marginTop="10dip"
android:background="#android:color/darker_gray">
<ImageView
android:id="#+id/ImageView1_l3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/twitter" />
<ImageView
android:id="#+id/ImageView2_l3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/ImageView3_l3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dip"
android:id="#+id/ll4"
android:layout_marginTop="10dip"
android:background="#android:color/darker_gray">
<ImageView
android:id="#+id/ImageView1_l4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/twitter" />
<ImageView
android:id="#+id/ImageView2_l4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/ImageView3_l4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
</LinearLayout>
</com.example.dragvdropdemo.MyScrollView>
i want to drag and drop image from one to another layout.i don't know how to solve it. i have tried but i could do it.i'm don't know veryand my code is:
public class MyActivity extends Activity {
ImageView img1,img2,img3,img01;
ImageView img02,img03,img1_l3,img2_l3,img3_l3,img1_l4,img2_l4,img3_l4;
LinearLayout ll1,ll2,ll3,ll4,lldrag;
MyScrollView myScrollView;
int mScrollDistance;
private static int oldvalue;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.mylist);
//SCROLLVIEW
myScrollView = (MyScrollView) findViewById(R.id.scroll_view);
myScrollView.setOnScrollViewListener(new MyScrollView.OnScrollViewListener() {
#Override
public void onScrollChanged1(OnScrollViewListener listener) {
// TODO Auto-generated method stub
mScrollDistance = myScrollView.getScrollY();
}
});
img1 = (ImageView)findViewById(R.id.imageView1);
img2 = (ImageView)findViewById(R.id.imageView2);
img3 = (ImageView)findViewById(R.id.imageView3);
img01 = (ImageView)findViewById(R.id.ImageView01);
img02 = (ImageView)findViewById(R.id.ImageView02);
img03 = (ImageView)findViewById(R.id.ImageView03);
img1_l3 = (ImageView)findViewById(R.id.ImageView1_l3);
img2_l3 = (ImageView)findViewById(R.id.ImageView2_l3);
img3_l3 = (ImageView)findViewById(R.id.ImageView3_l3);
img1_l4 = (ImageView)findViewById(R.id.ImageView1_l4);
img2_l4 = (ImageView)findViewById(R.id.ImageView2_l4);
img3_l4 = (ImageView)findViewById(R.id.ImageView3_l4);
ll1 = (LinearLayout)findViewById(R.id.ll1);
ll2 = (LinearLayout)findViewById(R.id.ll2);
ll3 = (LinearLayout)findViewById(R.id.ll3);
ll4 = (LinearLayout)findViewById(R.id.ll4);
lldrag = (LinearLayout)findViewById(R.id.lldrag);
img1.setOnTouchListener(new ChoiceTouchListener());
img2.setOnTouchListener(new ChoiceTouchListener());
img3.setOnTouchListener(new ChoiceTouchListener());
img01.setOnTouchListener(new ChoiceTouchListener());
img02.setOnTouchListener(new ChoiceTouchListener());
img03.setOnTouchListener(new ChoiceTouchListener());
img1_l3.setOnTouchListener(new ChoiceTouchListener());
img2_l3.setOnTouchListener(new ChoiceTouchListener());
img3_l3.setOnTouchListener(new ChoiceTouchListener());
img1_l4.setOnTouchListener(new ChoiceTouchListener());
img2_l4.setOnTouchListener(new ChoiceTouchListener());
img3_l4.setOnTouchListener(new ChoiceTouchListener());
ll1.setOnDragListener(new ChoiceDragListener());
ll2.setOnDragListener(new ChoiceDragListener());
ll3.setOnDragListener(new ChoiceDragListener());
ll4.setOnDragListener(new ChoiceDragListener());
lldrag.setOnDragListener(new ChoiceDragListener());
}
private final class ChoiceTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
ClipData data=ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
//start dragging the item touched''
view.startDrag(data, shadowBuilder, view, 0);
return true;
}
}
/**
* DragListener will handle dragged views being dropped on the drop area
* - only the drop action will have processing added to it as we are not
* - amending the default behavior for other parts of the drag process
*
*/
class ChoiceDragListener implements OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
//no action necessary
Log.i("", "DRAGSTARTED");
break;
case DragEvent.ACTION_DRAG_ENTERED:
//no action necessary
Log.i("","DRAGENTERED");
break;
case DragEvent.ACTION_DRAG_EXITED:
//no action necessary
Log.i("","DRAGEXITED");
break;
case DragEvent.ACTION_DROP:
//handle the dragged view being dropped over a drop view
Log.i("","DROP");
View view = (View) event.getLocalState();
LinearLayout ll=(LinearLayout) view.getParent();
ll.removeView(view);
LinearLayout dropTarget = (LinearLayout) v;
ImageView dropped = (ImageView) view;
dropTarget.addView(dropped,0);
Object tag = dropTarget.getTag();
if(tag!=null)
{
int existingID = (Integer)tag;
findViewById(existingID).setVisibility(View.VISIBLE);
}
//set the tag in the target view being dropped on - to the ID of the view being dropped
dropTarget.setTag(dropped.getId());
break;
case DragEvent.ACTION_DRAG_LOCATION:
//no action necessary
int y = Math.round(event.getY());
int translatedY = y - mScrollDistance;
Log.i("translated",""+translatedY+" "+ mScrollDistance+" "+y);
int threshold =50 ;
// make a scrolling up due the y has passed the threshold
if (translatedY < threshold) {
// make a scroll up by 30 px
myScrollView.scrollBy(0, -30);
}
// make a autoscrolling down due y has passed the 500 px border
if (translatedY + threshold > 200) {
// make a scroll down by 30 px
myScrollView.scrollBy(0, 30);
}
break;
case DragEvent.ACTION_DRAG_ENDED:
//no action necessary
break;
default:
break;
}
return true;
}
}
}
MySrollView
public class MyScrollView extends ScrollView {
public OnScrollViewListener mListener;
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
if (mListener != null) {
mListener.onScrollChanged1(mListener);
}
}
public void setOnScrollViewListener(OnScrollViewListener listener) {
mListener = listener;
}
public static interface OnScrollViewListener {
public void onScrollChanged1(OnScrollViewListener listener);
}
}
i'm android beginner so don't know it very well so tell me how to solve it.
sorry for my bad english and grammer mistake.
thanks in advances
I solved this problem by myself. Here is the solution:
DragEvent.ACTION_DRAG_LOCATION:
//no action necessary
int y = Math.round(v.getY())+Math.round(event.getY());
int translatedY = y - mScrollDistance;
Log.i("translated",""+translatedY+" "+ mScrollDistance+" "+y);
int threshold =50 ;
// make a scrolling up due the y has passed the threshold
if (translatedY < 200) {
// make a scroll up by 30 px
myScrollView.smoothScrollBy(0, -15);
}
// make a autoscrolling down due y has passed the 500 px border
if (translatedY + threshold > 500) {
// make a scroll down by 30 px
myScrollView.smoothScrollBy(0, 15);
}
break;

Implementing a slider (SeekBar) in Android

I want to implement a slider, which is basically two lines, one vertical and one horizontal, crossing where the screen is touched. I have managed to make one but I have to issues:
The slider is not very smooth, there is a slight delay when I'm moving the finger
If I place two sliders it is not multitouch, and I'd like to use both of them simultaneously
Here is the code:
public class Slider extends View {
private Controller controller = new Controller();
private boolean initialisedSlider;
private int sliderWidth, sliderHeight;
private Point pointStart;
private Paint white;
private int mode;
final static int VERTICAL = 0, HORIZONTAL = 1, BOTH = 2;
public Slider(Context context) {
super(context);
setFocusable(true);
// TODO Auto-generated constructor stub
}
public Slider(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
pointStart = new Point();
initialisedSlider = false;
mode = Slider.BOTH;
}
#Override
protected void onDraw(Canvas canvas) {
if(!initialisedSlider) {
initialisedSlider = true;
sliderWidth = getMeasuredWidth();
sliderHeight = getMeasuredHeight();
pointStart.x = (int)(sliderWidth/2.0);
pointStart.y = (int)(sliderHeight/2.0);
controller = new Controller(pointStart, 3);
white = new Paint();
white.setColor(0xFFFFFFFF);
}
canvas.drawLine(controller.getCoordX(),0,
controller.getCoordX(),sliderHeight,
white);
canvas.drawLine(0, controller.getCoordY(),
sliderWidth, controller.getCoordY(),
white);
}
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:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
case MotionEvent.ACTION_MOVE:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
case MotionEvent.ACTION_UP:
if(isInBounds(X,Y)) {
updateController(X, Y);
}
break;
}
invalidate();
return true;
}
private boolean isInBounds(int x, int y) {
return ((x<=(sliderWidth)) && (x>=(0))
&& (y<=(sliderHeight)) && (y>=(0)));
}
private void updateController(int x, int y) {
switch(mode) {
case Slider.HORIZONTAL:
controller.setCoordX(x);
break;
case Slider.VERTICAL:
controller.setCoordY(y);
break;
case Slider.BOTH:
controller.setCoordX(x);
controller.setCoordY(y);
break;
}
}
private class Controller {
private int coordX, coordY;
Controller() {
}
Controller(Point point, int width) {
setCoordX(point.x);
setCoordY(point.y);
}
public void setCoordX(int coordX) {
this.coordX = coordX;
}
public int getCoordX() {
return coordX;
}
public void setCoordY(int coordY) {
this.coordY = coordY;
}
public int getCoordY() {
return coordY;
}
}
}
And the XML file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
<com.android.lasttest.Slider
android:id="#+id/slider"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"/>
</LinearLayout>
How to implement a SeekBar
Add the SeekBar to your layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<SeekBar
android:id="#+id/seekBar"
android:max="100"
android:progress="50"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Notes
max is the highest value that the seek bar can go to. The default is 100. The minimum is 0. The xml min value is only available from API 26, but you can just programmatically convert the 0-100 range to whatever you need for earlier versions.
progress is the initial position of the slider dot (called a "thumb").
For a vertical SeekBar use android:rotation="270".
Listen for changes in code
public class MainActivity extends AppCompatActivity {
TextView tvProgressLabel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// set a change listener on the SeekBar
SeekBar seekBar = findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(seekBarChangeListener);
int progress = seekBar.getProgress();
tvProgressLabel = findViewById(R.id.textView);
tvProgressLabel.setText("Progress: " + progress);
}
SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// updated continuously as the user slides the thumb
tvProgressLabel.setText("Progress: " + progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// called when the user first touches the SeekBar
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// called after the user finishes moving the SeekBar
}
};
}
Notes
If you don't need to do any updates while the user is moving the seekbar, then you can just update the UI in onStopTrackingTouch.
See also
SeekBar Tutorial With Example In Android Studio
Android provides slider which is horizontal
http://developer.android.com/reference/android/widget/SeekBar.html
and implement OnSeekBarChangeListener
http://developer.android.com/reference/android/widget/SeekBar.OnSeekBarChangeListener.html
If you want vertical Seekbar then follow this link
http://hoodaandroid.blogspot.in/2012/10/vertical-seek-bar-or-slider-in-android.html
For future readers!
Starting from material components android 1.2.0-alpha01, you have slider component
ex:
<com.google.android.material.slider.Slider
android:id="#+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:valueFrom="20f"
android:valueTo="70f"
android:stepSize="10" />
Release notes
Material Design Spec
Docs

Categories

Resources