Make differents between setOnClickListener and setOnTouchListener - android

I need some help. In my android app I have a ViewFlipper that contains some LinearLayout. On every LinearLayout I have a ImageView. For switching between screens I use this code :
LinearLayout layMain = (LinearLayout) findViewById(R.id.layout_main);
layMain.setOnTouchListener((OnTouchListener) this);
//--------------
public boolean onTouch(View arg0, MotionEvent arg1) {
// Get the action that was done on this touch event
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN: {
// store the X value when the user's finger was pressed down
downXValue = arg1.getX();
break;
}
case MotionEvent.ACTION_UP: {
// Get the X value when the user released his/her finger
float currentX = arg1.getX();
// going backwards: pushing stuff to the right
if (downXValue < currentX) {
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
// Set the animation
vf.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_out));
vf.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_in));
// Flip!
vf.showPrevious();
}
// going forwards: pushing stuff to the left
if (downXValue > currentX) {
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
// Set the animation
// vf.setInAnimation(AnimationUtils.loadAnimation(this,
// R.anim.push_left_in));
vf.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
vf.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
// Flip!
vf.showNext();
}
break;
}
}
// if you return false, these actions will not be recorded
return true;
}
Every screen contains a ImageView.So, when I switch the screens the imageview is changing. Now I want to implement this: When an image is clicked a url to be open. Here is my code :
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
for (i = 0; i < jArray.length(); i++) {
LinearLayout l = new LinearLayout(this);
l.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
l.setBackgroundColor(0x000000);
l.setOrientation(LinearLayout.VERTICAL);
vf.addView(l);
ImageView img = new ImageView(this);
img.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
Drawable image1 = ImageOperations(getBaseContext(), url[i]);
img.setImageDrawable(image1);
System.out.println("target" + target[i]);
img.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri
.parse("http://google.com"));
startActivity(browserIntent);
}
});
l.addView(img);
}
The problem is that everytime I touch the screen the url is open and now I can't switch between screens. How to do this, to make the differents between onClick() and on Touch()?
Please help me..
Thanks in advance

I think you use image View like a background for Linear Layout , it seems Activity handle the touch for ImageView , to achieve your Functionality setTouch listener for imageView and we can handle the click for image view indirectly using following code in OntouchListener,
if (downXValue == currentX) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri
.parse("http://google.com"));
startActivity(browserIntent);}

I got your problem but the thing is, for switching screens you should use, Viewflipper onTouchlistener like:
mFlipper.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
//// your touch code
instead of Linearlayout touch listeners.
then you can use normal touch listeners for your Imageview events
Hope it helps.

Related

Implement feature like iOS app closing vertical Swipe-to-Dismiss with ViewPager

I currently have Views lined up horizontally in a ViewPager and can cycle through them with a PagerAdapter. Currently, to perform the action that I would like to do on swipe, I have to do a double-tap on the View's page. I could post code, but it's somewhat difficult to extract the necessary pieces...
What I would like is the ability to swipe vertically on these views, have them translate vertically with swipe and fade-out, and then perform an action when they reach a certain distance away from the edge of the device.
To get an idea of what I am thinking, in the Gallery app you can pinch an opened photo to zoom-out and open a horizontal filmstrip view. From there you can swipe up (or down) on a photo/video to delete it. For those who do not have the same Gallery app, it's exactly like closing applications on iOS.
I've tried scanning though the source code for the Gallery app, but no luck finding the correct Activity.
view.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent motion) {
float y = motion.getY();
/* NOTE: the following line might need to be in runOnUiThread() */
view.animate().alpha(1-Math.abs(y-height/2)/(height/2)).setDuration(50).start();
return true; //false if you want to pass this event on to other listeners
}
});
The explanation for using 1-Math.abs(y-height/2)/(height/2) is that I want alpha to be 1 when I am in the center, and alpha to be 0 when it is at the top or bottom. You have to determine yourself how you obtain the height value, or if you want to use a different method to calculate alpha. If you want to get the touch position relative to the screen instead of the position relative to the view, use getRawY().
Additionally, it may be useful for you to know that to see if the MotionEvent is a press, drag, or release event, use
motion.getAction() == with MotionEvent.ACTION_UP, MotionEvent.ACTION_MOVE, and MotionEvent.ACTION_DOWN, respectively.
I ended up getting this working more-or-less by cloning the well-written Android-SwipeToDismiss library and just replacing the ListView code with a ViewPager.
The finished product looked like this.
Check the below code, this may helpful to you:
public class MainActivity extends Activity implements View.OnTouchListener{
private RelativeLayout baseLayout;
private int previousFingerPosition = 0;
private int baseLayoutPosition = 0;
private int defaultViewHeight;
private boolean isClosing = false;
private boolean isScrollingUp = false;
private boolean isScrollingDown = false;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popup);
baseLayout = (RelativeLayout) findViewById(R.id.base_popup_layout);//this is the main layout
baseLayout.setOnTouchListener(this);
}
public boolean onTouch(View view, MotionEvent event) {
// Get finger position on screen
final int Y = (int) event.getRawY();
// Switch on motion event type
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// save default base layout height
defaultViewHeight = baseLayout.getHeight();
// Init finger and view position
previousFingerPosition = Y;
baseLayoutPosition = (int) baseLayout.getY();
break;
case MotionEvent.ACTION_UP:
// If user was doing a scroll up
if(isScrollingUp){
// Reset baselayout position
baseLayout.setY(0);
// We are not in scrolling up mode anymore
isScrollingUp = false;
}
// If user was doing a scroll down
if(isScrollingDown){
// Reset baselayout position
baseLayout.setY(0);
// Reset base layout size
baseLayout.getLayoutParams().height = defaultViewHeight;
baseLayout.requestLayout();
// We are not in scrolling down mode anymore
isScrollingDown = false;
}
break;
case MotionEvent.ACTION_MOVE:
if(!isClosing){
int currentYPosition = (int) baseLayout.getY();
// If we scroll up
if(previousFingerPosition >Y){
// First time android rise an event for "up" move
if(!isScrollingUp){
isScrollingUp = true;
}
// Has user scroll down before -> view is smaller than it's default size -> resize it instead of change it position
if(baseLayout.getHeight()<defaultViewHeight){
baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition);
baseLayout.requestLayout();
}
else {
// Has user scroll enough to "auto close" popup ?
if ((baseLayoutPosition - currentYPosition) > defaultViewHeight / 4) {
closeUpAndDismissDialog(currentYPosition);
return true;
}
//
}
baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition));
}
// If we scroll down
else{
// First time android rise an event for "down" move
if(!isScrollingDown){
isScrollingDown = true;
}
// Has user scroll enough to "auto close" popup ?
if (Math.abs(baseLayoutPosition - currentYPosition) > defaultViewHeight / 2)
{
closeDownAndDismissDialog(currentYPosition);
return true;
}
// Change base layout size and position (must change position because view anchor is top left corner)
baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition));
baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition);
baseLayout.requestLayout();
}
// Update position
previousFingerPosition = Y;
}
break;
}
return true;
}
}
For animation use the below methods:
public void closeUpAndDismissDialog(int currentPosition){
isClosing = true;
ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, -baseLayout.getHeight());
positionAnimator.setDuration(300);
positionAnimator.addListener(new Animator.AnimatorListener()
{
. . .
#Override
public void onAnimationEnd(Animator animator)
{
finish();
}
. . .
});
positionAnimator.start();
}
public void closeDownAndDismissDialog(int currentPosition){
isClosing = true;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenHeight = size.y;
ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, screenHeight+baseLayout.getHeight());
positionAnimator.setDuration(300);
positionAnimator.addListener(new Animator.AnimatorListener()
{
. . .
#Override
public void onAnimationEnd(Animator animator)
{
finish();
}
. . .
});
positionAnimator.start();
}

How to set finger touch functionality in android?

I am developing a small application in android in which i have few image in my application i want when user touch with one finger images can move left or right side and when user can touch with two fingers it could be zoom how can i do this please refer some tutorial code for me.
here is my code
and i used view flipper in xml v fdjf
public class Jaap extends Activity implements OnTouchListener{
float downXValue;
int counter = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
// Set main.XML as the layout for this Activity
setContentView(R.layout.jaap);
// Add these two lines
LinearLayout layMain = (LinearLayout) findViewById(R.id.layout_main);
layMain.setOnTouchListener((OnTouchListener) this);
// Add a few countries to the spinner
}
public boolean onTouch(View arg0, MotionEvent arg1) {
// Get the action that was done on this touch event
switch (arg1.getAction())
{
case MotionEvent.ACTION_DOWN:
{
// store the X value when the user's finger was pressed down
downXValue = arg1.getX();
break;
}
case MotionEvent.ACTION_UP:
{
// Get the X value when the user released his/her finger
float currentX = arg1.getX();
// going backwards: pushing stuff to the right
if (downXValue < currentX)
{
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
// Set the animation
// vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));
// Flip!
if(counter > 0){
vf.showPrevious();
counter--;
}
}
// going forwards: pushing stuff to the left
if (downXValue > currentX)
{
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
// Set the animation
// vf.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
// Flip!
if(counter < 131){
vf.showNext();
counter++;
}
}
break;
}
}
// if you return false, these actions will not be recorded
return true;
}
}
Check out this step-by-step tutorial, it contains code examples how to zoom in/out a picture and move it around.
Handle the MotionEvent in the onTouchEvent(MotionEvent) of the Activity.
In this check for the MotionEvent.getAction().
switch(MotionEvent.GetAction()) {
case ACTION_DOWN:
//handle the finger down functionality here
break;
case ACTION_POINTER_DOWN:
//handle the second finger down functionality here
break;
}
A sequence of events would be issued, mostly with the actions as follows:
ACTION_DOWN - one finger touch down
ACTION_MOVE -> the finger is moved
ACTION_UP - one finger touch is removed
ACTION_POINTER_DOWN - second finger touch down
ACTION_POINTER_UP - second finger touch up
You will have to check the X,Y positions in the event and determine what should be donw...
will see if there are any good tutorials/samples to explain these better...
getPointerCount() of motionEvent tells you how many fingers are touch. In gives number of touch
Thanks

The view, which was added with addView do not Flip (using ViewFlipper, Android)

The problem is that all the views, added to main.xml are flipping correctly - after the last view goes first view, after first -goes last, its rounded, but if i add the view using method addView of ViewFlipper class it won't flip "rounded" it will stop on it and do some incorrect animation, it won't go to next view and will go to previous only if there was done only 1 flip to the end.
Please, say how to make it works as a round 1->2->3->1.
Here's the code of flipper realization:
public class Activity1 extends Activity implements OnTouchListener{
float downXValue;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Set main.XML as the layout for this Activity
// Add these two lines
LinearLayout layMain = (LinearLayout) findViewById(R.id.layout_main);
layMain.setOnTouchListener((OnTouchListener) this);
}
public boolean onTouch(View arg0, MotionEvent arg1) {
// Get the action that was done on this touch event
switch (arg1.getAction())
{
case MotionEvent.ACTION_DOWN:
{
// store the X value when the user's finger was pressed down
downXValue = arg1.getX();
break;
}
case MotionEvent.ACTION_UP:
{
// Get the X value when the user released his/her finger
float currentX = arg1.getX();
View view = new View(this);
//HERE IS DECLARATION OF VIEW WHICH I NEED TO ADD
GraphicsView myview=new GraphicsView(this);
// going backwards: pushing stuff to the right
if (downXValue < currentX)
{
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
vf.addView(myview);
// Set the animation
vf.setInAnimation(view.getContext(), R.anim.push_right_in);
vf.setOutAnimation(view.getContext(), R.anim.push_right_out);
// Flip!
vf.showNext();
}
// going forwards: pushing stuff to the left
if (downXValue > currentX)
{
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
//HERE I'M ADDING IT
vf.addView(myview);
// Set the animation
vf.setInAnimation(view.getContext(), R.anim.push_left_in);
vf.setOutAnimation(view.getContext(), R.anim.push_left_out);
// Flip!
vf.showPrevious();
}
break;
}
}
// if you return false, these actions will not be recorded
return true;
}
Please, help. And answer plz if possible to add in main.xml the objects, that i defined in the code like myview is class object of GraphicsView, which extends from View.
Regards,
Keem
As per your code that you post, In your code you are adding view dynamically, on Touch Events, so as many time you touch your device screen, your OnTouch() call and every touch call this..
GraphicsView myview=new GraphicsView(this);
and also this.. ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
vf.addView(myview);
so on every touch you adding a view, and may be thats why you not getting right flipping.
For your solution, you should follow correct flow - may be as follows
in OnCreate() add different view in viewFlipper, out side your OnTouch().
In OnTouch() you set your animation and call vf.showPrevious() orvf.showNext() for propper navigation.

Move Events AFTER LongPress

How can I listen the move events after the LongPress is caled in my GestureDetector?
When the user LongClick he starts the selection mode, and can drag a square into the screen. But I noticed that the onScroll is not called after LongPress is consumed.
Tried to do fight this for a while, and for now the solution is:
Disable the longpress using setIsLongpressEnabled(isLongpressEnabled) on your gestureDetector
Here is my OnTouch method of my View:
public boolean onTouchEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event)== true)
{
//Fling or other gesture detected (not logpress because it is disabled)
}
else
{
//Manually handle the event.
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
//Remember the time and press position
Log.e("test","Action down");
}
if (event.getAction() == MotionEvent.ACTION_MOVE)
{
//Check if user is actually longpressing, not slow-moving
// if current position differs much then press positon then discard whole thing
// If position change is minimal then after 0.5s that is a longpress. You can now process your other gestures
Log.e("test","Action move");
}
if (event.getAction() == MotionEvent.ACTION_UP)
{
//Get the time and position and check what that was :)
Log.e("test","Action down");
}
}
return true;
}
My device returned ACTION_MOVE whenever I hold finger on the screen. If your doesnt, just check the state of some pressed flag after 0.5s using a timer or thread.
Hope that helps!
I have done this task by using the following concepts:
Suppose I have the Image View and on long press on it, image inside this image View would be drag-able and placed inside the another view(e.g. Relative Layout)
Set MyClickListner on Image View's setOnLongClickListener() method.
private final class MyClickListener implements View.OnLongClickListener {
// called when the item is long-clicked
#Override
public boolean onLongClick(View view) {
// TODO Auto-generated method stub
// create it from the object's tag
ClipData.Item item = new ClipData.Item((CharSequence)view.getTag());
String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN };
ClipData data = new ClipData(view.getTag().toString(), mimeTypes, item);
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag( data, //data to be dragged
shadowBuilder, //drag shadow
view, //local data about the drag and drop operation
0 //no needed flags
);
// view.setVisibility(View.INVISIBLE);
return true;
}
}
Then set MyDragListner on Relative Layout(e.g. bigImageRelativeLayoutVw.setOnDragListener(new MyDragListener());)
class MyDragListener implements View.OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
int X=(int)event.getX();
int Y=(int)event.getY();
int touchX = 0,touchY=0;
// Handles each of the expected events
switch (event.getAction()) {
//signal for the start of a drag and drop operation.
case DragEvent.ACTION_DRAG_STARTED:
// do nothing
break;
//the drag point has entered the bounding box of the View
case DragEvent.ACTION_DRAG_ENTERED:
break;
//the user has moved the drag shadow outside the bounding box of the View
case DragEvent.ACTION_DRAG_EXITED:
// v.setBackground(normalShape); //change the shape of the view back to normal
break;
//drag shadow has been released,the drag point is within the bounding box of the View
case DragEvent.ACTION_DROP:
// if the view is the bottomlinear, we accept the drag item
if(v == bigImageRelativeLayoutVw) {
View view = (View) event.getLocalState();
touchX=X-viewCoords[0]-20;
touchY=Y-viewCoords[1]-20;
View view1=new View(getActivity());
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(30,30);
layoutParams.leftMargin =touchX;
layoutParams.topMargin = touchY;
view1.setBackgroundResource(R.drawable.heavy_damage);
view1.setLayoutParams(layoutParams);
RelativeLayout containView = (RelativeLayout) v;
containView.addView(view1);
view.setVisibility(View.VISIBLE);
} else {
View view = (View) event.getLocalState();
view.setVisibility(View.VISIBLE);
break;
}
break;
//the drag and drop operation has concluded.
case DragEvent.ACTION_DRAG_ENDED:
// v.setBackground(normalShape); //go back to normal shape
default:
break;
}
return true;
}
}

Android Home Screen effect

I want to do something like andriod home screen effect. when i click the screen and move. the current view will move and next view also can show.
Now the code only can show the current view.
Thank you for your help
The source as follow:
public class test extends Activity implements OnTouchListener{
float downXValue;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set main.XML as the layout for this Activity
setContentView(R.layout.main);
// Add these two lines
LinearLayout layMain = (LinearLayout) findViewById(R.id.layout_main);
layMain.setOnTouchListener((OnTouchListener) this);
// Add a few countries to the spinner
Spinner spinnerCountries = (Spinner) findViewById(R.id.spinner_country);
ArrayAdapter countryArrayAdapter = new ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,new String[] { "Canada", "USA" });
spinnerCountries.setAdapter(countryArrayAdapter);
}
public boolean onTouch(View arg0, MotionEvent arg1) {
// Get the action that was done on this touch event
switch (arg1.getAction())
{
case MotionEvent.ACTION_DOWN:
{
// store the X value when the user's finger was pressed down
downXValue = arg1.getX();
break;
}
case MotionEvent.ACTION_UP:
{
// Get the X value when the user released his/her finger
float currentX = arg1.getX();
// going backwards: pushing stuff to the right
if (downXValue < currentX)
{
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
// Set the animation
vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));
// Flip!
vf.showPrevious();
}
// going forwards: pushing stuff to the left
if (downXValue > currentX)
{
// Get a reference to the ViewFlipper
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
// Set the animation
vf.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
// Flip!
vf.showNext();
}
break;
}
case MotionEvent.ACTION_MOVE:
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
final View currentView = vf.getCurrentView();
currentView.layout((int)(arg1.getX() - downXValue),
currentView.getTop(), currentView.getRight(),
currentView.getBottom());
/*may be do something in thest*/
break;
}
// if you return false, these actions will not be recorded
return true;
}
}
You can use Viewpager.tofeeq ahmad says:
Viewpager is the best way to switching among view. It provide a way
to swipe views from left to right and right to left. Viewpager provide
strong way to swipe any views.
You have to extend PagerAdapter and then use Viewpager.You can see snippet and full source code in Guidance on Android, Java and Other mobile Technology.

Categories

Resources