I'm developing an android app where the user can drag an ImageView to another ImageView. The ImageView needs to be changed in to dragged ImageView if it meets a certain condition and if it doesnt it should snap back to where it was.I tried doing it but i can't get it to work.
code behind the xml file
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2"
android:columnWidth="320dp"
android:orientation="vertical"
android:rowCount="14"
android:stretchMode="columnWidth" >
<LinearLayout
android:id="#+id/topleft"
android:layout_width="match_parent"
android:layout_height="413dp"
android:layout_row="0"
android:background="#drawable/shape" >
<ImageView
android:id="#+id/test_house"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/test_house" />
</LinearLayout>
<LinearLayout
android:id="#+id/topright"
android:layout_width="match_parent"
android:layout_height="106dp"
android:background="#drawable/shape"
android:layout_row="13"
android:layout_column="0"
android:weightSum="1">
<ImageView
android:id="#+id/house"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/house"
android:layout_weight="0.26" />
<ImageView
android:id="#+id/face"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/face"
android:layout_weight="0.24" />
<ImageView
android:id="#+id/duck"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/duck"
android:layout_weight="0.24" />
</LinearLayout>
</GridLayout>
code behind java file
public class cs_game_one extends Activity {
boolean state;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cs_game_one);
findViewById(R.id.test_house).setOnTouchListener(new MyTouchListener());
findViewById(R.id.house).setOnTouchListener(new MyTouchListener());
findViewById(R.id.face).setOnTouchListener(new MyTouchListener());
findViewById(R.id.duck).setOnTouchListener(new MyTouchListener());
findViewById(R.id.topleft).setOnDragListener(new MyDragListener());
findViewById(R.id.topright).setOnDragListener(new MyDragListener());
}
private final class MyTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, view, 0);
view.setVisibility(View.INVISIBLE);
return true;
} else {
return false;
}
}
}
class MyDragListener implements OnDragListener {
#Override
public boolean onDrag(View v, DragEvent e) {
if (e.getAction() == DragEvent.ACTION_DROP) {
View view = (View) e.getLocalState();
if (view.getId() == R.id.house && v.getId() == R.id.test_house){
ViewGroup from = (ViewGroup) view.getParent();
from.removeView(view);
v.setBackgroundResource(R.drawable.house);
state = true;
} else {
state = false;
}
}
return state;
}
}
}
After v.setBackgroundResource(R.drawable.house); add this:
v.invalidate();
This tells your UI thread that it needs to redraw that view that you are trying to set to the house Drawable.
In your else statement, change to this:
state = false;
view.setVisibility(View.VISIBLE); //This will make it look like your dragged image snaps back to it's original spot.
The interesting thing about drag and drop in Android is that when you start the drag, it's just hiding the image you originally touched (view in your code) when the drag started. The image you see moving around the screen under your finger is actually the drag shadow. Thus by changing the visibility of view in your else statement, it looks like the image snaps back to where you started the drag.
Related
I need to open phone's contact book on the click of EditText's drawableRight. Click event on drawableRight is working fine But the problem is, when I click/touch on anywhere on EditText it is also execute click event and open contact list.
I take help for manage click event on drawableRight from here Please check this link.
I don't want to open contact list when I click on EditText, I only want to open it when I click drawableRight (image). So how solve this problem?
Here is my code:
EditText mobile_number;
mobile_number = (EditText)view.findViewById(R.id.mobile_number1);
mobile_number.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;
if(event.getAction()==MotionEvent.ACTION_UP){
if(event.getRawX()>=(mobile_number.getRight()-mobile_number.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width()));
{
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent,PICK_CONTACT);
return true;
}
}
return true;
}
});
Here is my layout code:
<LinearLayout
android:layout_width="fill_parent"
android:id="#+id/linearlayout_two1"
android:layout_below="#+id/linearlayout_one1"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="20dp"
android:orientation="vertical"
>
<EditText
android:layout_width="300dp"
android:hint="Enter Your Mobile Number"
android:textSize="15sp"
android:id="#+id/mobile_number1"
android:paddingLeft="30dp"
android:layout_height="wrap_content"
android:drawableRight="#drawable/editbox_icon"
/>
</LinearLayout>
Instead of using getRawX(), try replacing that line with
if (event.getX() >= (mobile_number.getWidth() - mobile_number
.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
EDIT: I believe View.getRight() returns the position of the right edge of the View relative to its parent, while TouchEvent.getRawX() returns the absolute X position on the screen.
EDIT AGAIN TO DEMONSTRATE MY POINT:
MainActivity.xml
<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="com.meremammal.www.edittextdrawable.MainActivity">
<!-- This layout is only here to demonstrate a situation that breaks the usage of getRawX() -->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true">
<EditText
android:id="#+id/edit_text"
android:layout_width="400dp"
android:layout_height="wrap_content"
android:text="Hello World!"
android:drawableRight="#android:drawable/ic_input_add"/>
</RelativeLayout>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
EditText mEditText;
Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
mEditText = (EditText) findViewById(R.id.edit_text);
mEditText.setOnTouchListener(new View.OnTouchListener() {
private float touchX = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
int drawableLeft = mEditText.getRight() - mEditText
.getCompoundDrawables()[2].getBounds().width();
// This detects the location of touch on ACTION_DOWN, but because it is
// using getRawX() and getRight() and the EditText's parent is not at the
// left of the screen, it will respond when clicked in the middle of the
// EditText. Instead, use getX() and EditText.getWidth()
if (event.getAction() == MotionEvent.ACTION_DOWN && event.getRawX() >= drawableLeft) {
touchX = event.getRawX();
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP && touchX >= drawableLeft) {
Toast.makeText(mContext, "Clicked Button", Toast.LENGTH_SHORT).show();
touchX = 0;
return true;
} else {
return mEditText.onTouchEvent(event);
}
}
});
}
}
You don't have access to the right image as far my knowledge, unless you create custom EditText class. I suggest to use a RelativeLayout, with one editText and one imageView, and set OnClickListener over the image view as below:
<RelativeLayout
android:id="#+id/rlSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:drawable/edit_text"
android:padding="5dip" >
<EditText
android:id="#+id/txtSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/imgSearch"
android:background="#00000000"
android:ems="10"/>
<ImageView
android:id="#+id/imgSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#drawable/btnsearch" />
</RelativeLayout>
Make a Linear layout with horizontal orientation and add a edit-text and image-view with proper weight..
Then Give on click for each item separately.....
Just chage the last return to false. Also you have to remove the comma ; at the end of if statement.
I have a fragment containing 6 imageviews in its layout of my android application. When I click on the images, It should toast me the id of the imageview. But instead it is toasting as false, when I click on any of the imageviews. My images are of triangular in shape and to check whether I have clicked inside or not of the image, I have used on touch listener in my project. But it is not showing me the id of the imageview when I click on it. I'm using a navigation drawer in my project and so I'm using here fragments instead of activity. Here is my code:
HomeFragment.java (Edited)
public class HomeFragment extends Fragment {
public HomeFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_home, container, false);
final OnTouchListener changeColorListener = new OnTouchListener() {
#Override
public boolean onTouch(final View v, MotionEvent event) {
Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache());
int color = 0;
try {
color = bmp.getPixel((int) event.getX(), (int) event.getY());
} catch (Exception e) {
}
if (color == Color.TRANSPARENT)
return false;
else {
//edited part
if(v.getId() == R.id.loginbutton){
Toast.makeText(getActivity(), "Login button", Toast.LENGTH_SHORT).show();
}
//edited part
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(getActivity(), v.getId(), Toast.LENGTH_SHORT).show();
break;
case MotionEvent.ACTION_OUTSIDE:
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_SCROLL:
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return true;
}
}
};
ImageView loginbutton=(ImageView)rootView.findViewById(R.id.loginbutton);
loginbutton.setDrawingCacheEnabled(true);
loginbutton.setOnTouchListener(changeColorListener);
ImageView flightbutton=(ImageView)rootView.findViewById(R.id.flightbutton);
flightbutton.setDrawingCacheEnabled(true);
flightbutton.setOnTouchListener(changeColorListener);
ImageView registerbutton=(ImageView)rootView.findViewById(R.id.hotelbutton);
registerbutton.setDrawingCacheEnabled(true);
registerbutton.setOnTouchListener(changeColorListener);
ImageView supportbutton=(ImageView)rootView.findViewById(R.id.supportbutton);
supportbutton.setDrawingCacheEnabled(true);
supportbutton.setOnTouchListener(changeColorListener);
ImageView aboutusbutton=(ImageView)rootView.findViewById(R.id.aboutusbutton);
aboutusbutton.setDrawingCacheEnabled(true);
aboutusbutton.setOnTouchListener(changeColorListener);
ImageView contactbutton=(ImageView)rootView.findViewById(R.id.contactbutton);
contactbutton.setDrawingCacheEnabled(true);
contactbutton.setOnTouchListener(changeColorListener);
return rootView;
}
}
fragment_home.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/supportbutton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="31dp"
android:background="#drawable/support" />
<ImageView
android:id="#+id/flightbutton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_above="#+id/supportbutton"
android:layout_alignLeft="#+id/supportbutton"
android:layout_marginBottom="17dp"
android:background="#drawable/flight3" />
<ImageView
android:id="#+id/hotelbutton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignBaseline="#+id/flightbutton"
android:layout_alignBottom="#+id/flightbutton"
android:layout_centerHorizontal="true"
android:background="#drawable/hotel2" />
<ImageView
android:id="#+id/aboutusbutton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignLeft="#+id/hotelbutton"
android:layout_below="#+id/flightbutton"
android:background="#drawable/aboutus" />
<ImageView
android:id="#+id/loginbutton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignBaseline="#+id/hotelbutton"
android:layout_alignBottom="#+id/hotelbutton"
android:layout_alignParentRight="true"
android:layout_marginRight="37dp"
android:background="#drawable/login" />
<ImageView
android:id="#+id/contactbutton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignLeft="#+id/loginbutton"
android:layout_centerVertical="true"
android:background="#drawable/contact"
android:fitsSystemWindows="false" />
</RelativeLayout>
Please correct me if I'm wrong.
Edit:
Actually my intention was to check which button was clicked actually. The problem is when I added the edited part and run the app, It's intersting that when I click on the contact image, actually the toast is showing as Login button. But I have given in the else condition with the id of the login imageview, so that when I click on the login image, it should trigger the toast. Instead on clicking the contact image, the toast for login is actually called. How is that possible? Is there any solution for it...
From the documentation of Toast.makeText() there are two makeText() methods:
public static Toast makeText (Context context, int resId, int duration)
public static Toast makeText (Context context, CharSequence text, int duration)
I assume you want to display the ID as a string, but in this case you are passing v.getId() which returns an int, so actually the first method is called, which looks for a resource. So in the first place you could make it
Toast.makeText(getActivity(), v.getId() + "", Toast.LENGTH_SHORT).show()
which will turn your second argument into a string.
I have two layouts and one imageView. The parent layout linearLayout1 have image background and its child layout relativeLayout1 have dark background. So when i move imageView on screen it display a selective area of linearLayout1 image . I applied touch motion but no idea how to display selective area. the code is here
public class MainActivity extends Activity {
// RelativeLayout viewRelative;
ImageButton imgBtnTarget;
Animation aniRotate, aniZoom;
PointF downPoint = new PointF();// Record Mouse Position When Pressed Down
PointF strtPointImg = new PointF(); // Record Start Position of 'img'
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgBtnTarget = (ImageButton) findViewById(R.id.imageButtontTarget);
imgBtnTarget.setOnTouchListener( new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// for moving image
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
PointF mv = new PointF(event.getX() - downPoint.x, event
.getY() - downPoint.y);
imgBtnTarget.setX((int) (strtPointImg.x + mv.x));
imgBtnTarget.setY((int) (strtPointImg.y + mv.y));
strtPointImg = new PointF(imgBtnTarget.getX(), imgBtnTarget.getY());
break;
}
return false;
}
});
}
}
and here is xml resource
<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:background="#drawable/back" >
<RelativeLayout
android:id="#+id/relativeViewBlack"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black" >
<ImageButton
android:id="#+id/imageButtontTarget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#android:color/transparent"
android:scaleType="fitCenter"
android:src="#drawable/target" />
</RelativeLayout>
In Java code:
LinearLayout ll = (LinearLayout) findViewById(R.id.your_ll_id);
ll.setAlpha(TRANSPARENT_VALUE);
Or:
ll.setBackgroundColor(Color.TRANSPARENT);
If you want transparent all from the begining add to your Layout in XML:
android:background="#00ffffff"
EDIT:
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
v.setAlpha(0.5f);
break;
case MotionEvent.ACTION_UP:
v.setAlpha(1.0f);
break;
case MotionEvent.ACTION_MOVE:
//your code...
break;
}
return true;
}
I have giving the full code that I have.
The code bellow can drag and drop very smoothly but it is not working like what I need like bellow description.
Drag Data Is (Apple, Orage, Ball)
Drop target location is (A for, O for, B for)
So, if drag "Apple" drop to "A for" it will be CORRECT and update text to "A for Apple" and Text "Apple" at drag will be hide... but if we drag "Apple" drop to "O for" or "B for" it will be failed because "O for Orange" and "B for Ball".
Based on the below code, what should I add.
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="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:paddingLeft="50dp"
android:paddingRight="50dp" >
<TextView
android:id="#+id/option_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/option"
android:gravity="center"
android:text="Apple"
android:textStyle="bold" />
<TextView
android:id="#+id/option_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/option"
android:gravity="center"
android:text="Orange"
android:textStyle="bold" />
<TextView
android:id="#+id/option_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/option"
android:gravity="center"
android:text="Ball"
android:textStyle="bold" />
<TextView
android:id="#+id/choice_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="A for " />
<TextView
android:id="#+id/choice_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="O for" />
<TextView
android:id="#+id/choice_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="B for " />
</LinearLayout>
Acvitity:
public class picture_to_word_24_color extends Activity {
//text views being dragged and dropped onto
private TextView option1, option2, option3, choice1, choice2, choice3;
public CharSequence dragData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picture_to_word_24_color);
//get both sets of text views
//views to drag
option1 = (TextView)findViewById(R.id.option_1);
option2 = (TextView)findViewById(R.id.option_2);
option3 = (TextView)findViewById(R.id.option_3);
//views to drop onto
choice1 = (TextView)findViewById(R.id.choice_1);
choice2 = (TextView)findViewById(R.id.choice_2);
choice3 = (TextView)findViewById(R.id.choice_3);
//set touch listeners
option1.setOnTouchListener(new ChoiceTouchListener());
option2.setOnTouchListener(new ChoiceTouchListener());
option3.setOnTouchListener(new ChoiceTouchListener());
//set drag listeners
choice1.setOnDragListener(new ChoiceDragListener());
choice2.setOnDragListener(new ChoiceDragListener());
choice3.setOnDragListener(new ChoiceDragListener());
}
/**
* ChoiceTouchListener will handle touch events on draggable views
*
*/
private final class ChoiceTouchListener implements OnTouchListener {
#SuppressLint("NewApi")
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
/*
* Drag details: we only need default behavior
* - clip data could be set to pass data as part of drag
* - shadow can be tailored
*/
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
//start dragging the item touched
view.startDrag(data, shadowBuilder, view, 0);
return true;
} else {
return false;
}
}
}
/**
* 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
*
*/
#SuppressLint("NewApi")
private class ChoiceDragListener implements OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
//no action necessary
break;
case DragEvent.ACTION_DRAG_ENTERED:
//no action necessary
Toast.makeText(picture_to_word_24_color.this, "ACTION_DRAG_ENTERED", Toast.LENGTH_SHORT).show();
break;
case DragEvent.ACTION_DRAG_EXITED:
//no action necessary
Toast.makeText(picture_to_word_24_color.this, "ACTION_DRAG_EXITED", Toast.LENGTH_SHORT).show();
break;
case DragEvent.ACTION_DROP:
Toast.makeText(picture_to_word_24_color.this, "ACTION_DROP", Toast.LENGTH_SHORT).show();
//handle the dragged view being dropped over a drop view
View view = (View) event.getLocalState();
//stop displaying the view where it was before it was dragged
view.setVisibility(View.INVISIBLE);
//view dragged item is being dropped on
TextView dropTarget = (TextView) v;
//view being dragged and dropped
TextView dropped = (TextView) view;
//update the text in the target view to reflect the data being dropped
dropTarget.setText(dropped.getText());
//make it bold to highlight the fact that an item has been dropped
dropTarget.setTypeface(Typeface.DEFAULT_BOLD);
//if an item has already been dropped here, there will be a tag
Object tag = dropTarget.getTag();
//if there is already an item here, set it back visible in its original place
if(tag!=null)
{
//the tag is the view id already dropped here
int existingID = (Integer)tag;
//set the original view visible again
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_ENDED:
//no action necessary
Toast.makeText(picture_to_word_24_color.this, "ACTION_DRAG_ENDED", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return true;
}
}
}
Try the following code, it should work according to your description in the question.
I have added an extra thing i.e. reset button as I felt it necessary.
picture_to_word_24_color.xml
<?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"
android:padding="10dp"
android:paddingLeft="50dp"
android:paddingRight="50dp" >
<TextView
android:id="#+id/option_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/option"
android:gravity="center"
android:text="Apple"
android:textStyle="bold" />
<TextView
android:id="#+id/option_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/option"
android:gravity="center"
android:text="Orange"
android:textStyle="bold" />
<TextView
android:id="#+id/option_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/option"
android:gravity="center"
android:text="Ball"
android:textStyle="bold" />
<TextView
android:id="#+id/choice_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="A for " />
<TextView
android:id="#+id/choice_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="O for " />
<TextView
android:id="#+id/choice_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="B for " />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reset"
android:onClick="reset"/>
</LinearLayout>
Picture_to_word_24_color.java
package com.example.touchanddrag;
import android.os.Build;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ClipData;
import android.graphics.Typeface;
import android.view.DragEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.widget.TextView;
import android.widget.Toast;
#SuppressLint("NewApi")
public class Picture_to_word_24_color extends Activity {
private TextView option1, option2, option3, choice1, choice2, choice3;
public CharSequence dragData;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picture_to_word_24_color);
//get both sets of text views
//views to drag
option1 = (TextView)findViewById(R.id.option_1);
option2 = (TextView)findViewById(R.id.option_2);
option3 = (TextView)findViewById(R.id.option_3);
//views to drop onto
choice1 = (TextView)findViewById(R.id.choice_1);
choice2 = (TextView)findViewById(R.id.choice_2);
choice3 = (TextView)findViewById(R.id.choice_3);
//set touch listeners
option1.setOnTouchListener(new ChoiceTouchListener());
option2.setOnTouchListener(new ChoiceTouchListener());
option3.setOnTouchListener(new ChoiceTouchListener());
//set drag listeners
choice1.setOnDragListener(new ChoiceDragListener());
choice2.setOnDragListener(new ChoiceDragListener());
choice3.setOnDragListener(new ChoiceDragListener());
}
/**
* ChoiceTouchListener will handle touch events on draggable views
*
*/
private final class ChoiceTouchListener implements OnTouchListener {
#SuppressLint("NewApi")
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
/*
* Drag details: we only need default behavior
* - clip data could be set to pass data as part of drag
* - shadow can be tailored
*/
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
//start dragging the item touched
view.startDrag(data, shadowBuilder, view, 0);
return true;
} else {
return false;
}
}
}
/**
* 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
*
*/
#SuppressLint("NewApi")
private class ChoiceDragListener implements OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
//no action necessary
break;
case DragEvent.ACTION_DRAG_ENTERED:
//no action necessary
break;
case DragEvent.ACTION_DRAG_EXITED:
//no action necessary
break;
case DragEvent.ACTION_DROP:
//handle the dragged view being dropped over a drop view
View view = (View) event.getLocalState();
//view dragged item is being dropped on
TextView dropTarget = (TextView) v;
//view being dragged and dropped
TextView dropped = (TextView) view;
//checking whether first character of dropTarget equals first character of dropped
if(dropTarget.getText().toString().charAt(0) == dropped.getText().toString().charAt(0))
{
//stop displaying the view where it was before it was dragged
view.setVisibility(View.INVISIBLE);
//update the text in the target view to reflect the data being dropped
dropTarget.setText(dropTarget.getText().toString() + dropped.getText().toString());
//make it bold to highlight the fact that an item has been dropped
dropTarget.setTypeface(Typeface.DEFAULT_BOLD);
//if an item has already been dropped here, there will be a tag
Object tag = dropTarget.getTag();
//if there is already an item here, set it back visible in its original place
if(tag!=null)
{
//the tag is the view id already dropped here
int existingID = (Integer)tag;
//set the original view visible again
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());
//remove setOnDragListener by setting OnDragListener to null, so that no further drag & dropping on this TextView can be done
dropTarget.setOnDragListener(null);
}
else
//displays message if first character of dropTarget is not equal to first character of dropped
Toast.makeText(Picture_to_word_24_color.this, dropTarget.getText().toString() + "is not " + dropped.getText().toString(), Toast.LENGTH_LONG).show();
break;
case DragEvent.ACTION_DRAG_ENDED:
//no action necessary
break;
default:
break;
}
return true;
}
}
public void reset(View view)
{
option1.setVisibility(TextView.VISIBLE);
option2.setVisibility(TextView.VISIBLE);
option3.setVisibility(TextView.VISIBLE);
choice1.setText("A for ");
choice2.setText("O for ");
choice3.setText("B for ");
choice1.setTag(null);
choice2.setTag(null);
choice3.setTag(null);
choice1.setTypeface(Typeface.DEFAULT);
choice2.setTypeface(Typeface.DEFAULT);
choice3.setTypeface(Typeface.DEFAULT);
choice1.setOnDragListener(new ChoiceDragListener());
choice2.setOnDragListener(new ChoiceDragListener());
choice3.setOnDragListener(new ChoiceDragListener());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.picture_to_word_24_color, menu);
return true;
}
}
Don't forget to check for target API level. As I had to add #SuppressLint("NewApi")
I can't get onTouch event triggered on a container when clicking on its ScrollView child.
I'm using API 12 on a Galaxy tab 10.1.
Anybody can help?
Thanks
Activity
public class TestActivity extends Activity{
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.dude);
LinearLayout mylayout = (LinearLayout) findViewById(R.id.mylayout);
mylayout.setOnTouchListener(new OnTouchListener () {
public boolean onTouch(View view, MotionEvent event) {
// Only called when touched outside the ScrollView
if (event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
/* do stuff */
} else if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
/* do stuff */
}
return true;
}
});
}
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mylayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="Touch here trigger parent's onTouch"
android:textColor="#000000"
android:textSize="40sp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="match_parent"
android:layout_height="1000dp"
android:background="#b00000"
android:gravity="center"
android:text="Touch here DOES NOT trigger parent's onTouch"
android:textColor="#000000"
android:textSize="40sp" />
</RelativeLayout>
</ScrollView>
</LinearLayout>
mylayout.setOnTouchListener(new OnTouchListener () {
public boolean onTouch(View view, MotionEvent event) {
// Only called when touched outside the ScrollView
if (event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
/* do stuff */
return true;
} else if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
/* do stuff */
return true;
}
return false;
}
});
this should work... but you no longer have auto-scroll when you fling it hard... it'll be a sticky scroll moving only as much as you drag.
Did u try to create ONE OnClickListener and add it to all childs?
Maybe this could solve your
As the ScrollView makes it childs scrollable it wouldn't have an own area to click in.
(Correct me if I'm wrong ^^)
You probably need this code
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
onTouchEvent(ev);
return false;
}