ViewPager Swipe with Button OnTouchListener event - android

I have a ViewPager with 2 items into it and a Button for ViewPager Animation . I wanted to swipe the ViewPager with the TouchEvent of Button without moving my finger up i.e Sliding my finger from Button & getting the ViewPager Swipe
Currently I am able to get A swipe only when I move Up my finger & swipe not on the TouchEvent
Below is My code Snippets...of XML
<Button
android:id="#+id/slide_btn_speak"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#android:drawable/ic_btn_speak_now"
android:contentDescription="#string/app_name" />
<TextView
android:id="#+id/slide_txtView_inside"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="#+id/slide_btn_speak"
android:text="#string/app_name" />
<android.support.v4.view.ViewPager
android:id="#+id/ui_pager"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/slide_btn_speak"
android:layout_toRightOf="#+id/slide_btn_speak"
android:scrollbars="horizontal" >
</android.support.v4.view.ViewPager>
<Button
android:id="#+id/slide_btn_drag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#android:drawable/ic_btn_speak_now"
android:contentDescription="#string/app_name" />
My Activity Snippets...
public class SlidingActitvity extends Activity {
ViewPager viewPager;
Button slide_button_start ;
Vibrator vibrator;
static int count ;
int x_position, y_position;
String hint[] ={" SWIPE TO CANCEL " , ""};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sliding_actitvity);
viewPager = (ViewPager) findViewById(R.id.ui_pager);
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
slide_button_start = (Button) findViewById(R.id.slide_btn_drag);
slide_button_start.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
int viewPager_width = viewPager.getWidth();
x_position = (int) event.getX();
y_position = (int) event.getY();
if(x_position<= 0){
vibrator.cancel();
viewPager.bringToFront();
logIt("Touch..." +x_position +"..."+y_position);
}
break;
case MotionEvent.ACTION_DOWN:
vibrator.vibrate(100);
final Animation animation = AnimationUtils.loadAnimation(SlidingActitvity.this, R.anim.left);
ViewPagerAdapter adapter = new ViewPagerAdapter(SlidingActitvity.this , hint);
viewPager.setAdapter(adapter);
viewPager.setVisibility(ViewPager.VISIBLE);
viewPager.setAnimation(animation);
logIt("Touch...Down");
break;
case MotionEvent.ACTION_UP:
logIt("Touch...Up");
vibrator.cancel();
break;
case MotionEvent.ACTION_OUTSIDE:
logIt("Your are out...");
vibrator.cancel();
break ;
default:
break;
}
return true;
}
});
}
Any Answer is Appreciated...

By returning true in the button's OnTouchListener, you're consuming the touch event. Specifically, the ViewPager needs to be informed of MotionEvent.ACTION_DOWN so that it can intercept touch events when it detects that it is being swiped.
You will need to carefully consider in which cases touch events get passed up the view hierarchy such that the ViewPager can continue to perform its magic.

Related

Android Ontouchlistener not showing correct id of the imageview when it's clicked

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.

How to use a view pager inside a navigation drawer? [duplicate]

I want to use a seekbar in a Navigation Drawer
Basically I need to slide left and right to set the seekbar and, well, you guessed it, it slides the navigation drawer...
What I would like to do is to slide the seekbar when it's focused and the navigationdrawer when it's not.
How should I do that?
Here is my code when setting an item (I haven't set the seekbar yet)
private View onCritereView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View mView = inflater.inflate(R.layout.fragment_critere, container, false);
LinearLayout mLinearLayout = (LinearLayout) mView.findViewById(R.id.critere_linearlayout);
View mViewElement = inflater.inflate(R.layout.item_critere, null);
((TextView)mViewElement.findViewById(R.id.critere_title)).setText("Prix Maximum");
mLinearLayout.addView(mViewElement);
return mView;
}
Here is the item_critere.xml with the seekbar:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/critere_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="*">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Large Text"
android:id="#+id/critere_title"
android:layout_gravity="left|center_vertical"
android:layout_column="0"/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/critere_qualifier"
android:layout_column="1"
android:layout_span="4"/>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Medium Text"
android:id="#+id/critere_value"
android:layout_span="4"/>
</TableRow>
</TableLayout>
Thanks in advance :)
Just add an onTouchListener. When you touch the screen on the seekbar (action_down) disallow parent to intercept the event.
seekbar.setOnTouchListener(new ListView.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
// Disallow Drawer to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
// Allow Drawer to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle seekbar touch events.
v.onTouchEvent(event);
return true;
}
});
Use DrawerLayout.setDrawerLockMode
instead of ViewParent.requestDisallowInterceptTouchEvent.
In #dumazy answer requestDisallowInterceptTouchEvent solves this issue but it also creates another.
While you are scrolling on navigation drawer, If you touch on SeekBar, OnSeekBarChangeListener will trigger. So scrolling event will break and seekbar progress will start to change by moving your finger.
I modified the original answer a little bit to solve this issue using DrawerLockMode:
mSeekBar.setOnTouchListener(new SeekBar.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow Drawer to intercept touch events.
// v.getParent().requestDisallowInterceptTouchEvent(true);
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Allow Drawer to intercept touch events.
// v.getParent().requestDisallowInterceptTouchEvent(false);
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNDEFINED);
break;
}
// Handle SeekBar touch events.
v.onTouchEvent(event);
return true;
}
});

how to make layouts transparent on click

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;
}

Pass click event through the view android

I have frame layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" >
<LinearLayout
android:id="#+id/widgetView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:gravity="center" >
</LinearLayout>
<LinearLayout
android:id="#+id/widgetOverlayFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false" >
</LinearLayout>
First layout contains widget layout, and second one is transparent and receives onLongClick for dragging method.That works, the problem is when i want to interact with widget, to click something, click event is taken by overlayFrame. How can i pass click event trough overlayFrame to widgetView?
EDIT:
Now I'm trying to attach GestureLister to overlayFrame LinearLayout, to somehow see difference between MotionEvent that represent single click and long click. The problem that I'm facing is that OnLongPress in gesture listener is always called whatever I do, single click or long click.
Is there an explanation for this behavior? Tnx!
In my case I added flag to layoutParams of my view, which should have passed a touch event under:
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
This way view will ignore all touches (like view with visibility GONE)
Instead of using GestureListener you can override the onTouchListener in this way.
This will call longPress when the timer runs out and if an up comes in between it will cancel the LongPress
CountDownTimer c;
long time=5000;
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
c= new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
time=millisUntilFinished;
}
public void onFinish() {
Log.i("","LONG PRESS");
}}.start();
break;
case MotionEvent.ACTION_UP:
if (time>0) {
Log.i("example","short click");
c.cancel();
}
break;
}
return true;
}
Maybe setting the overlay's attribute android:focusable="false" or android:focusableInTouchMode="false" would be enough.
You could also make your own overlay widget and override its onInterceptTouchEvent method to return false always.
public class NotTouchableLinearLayout extends LinearLayout {
// Override constructors
// ...
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}
Instead of setting a GestureListener on the top layout, you should create your own class that extends LinearLayout and to override it's onTouchEvent method.
There you can implement the logic of long click \ short click etc.
The click events will first be sent to the widget layout, and only if it doesn't handle them (hence it's onTouchEvent returns false), you will get them on the top layout.
edit:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" >
<LinearLayout
android:id="#+id/widgetView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:gravity="center" >
</LinearLayout>
<com.example.touchtesting.MyLinearLayout
android:id="#+id/widgetOverlayFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false" >
</com.example.touchtesting.MyLinearLayout>
</FrameLayout>
change the com.example.touchtesting to the name of your package.
and this is the class:
public class MyLinearLayout extends LinearLayout{
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
private long startClick = 0;
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startClick = ev.getEventTime();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (ev.getEventTime() - startClick < 500) {
Log.i("example","short click");
}
else {
Log.i("example","long click");
}
break;
}
return true;
}
}
To get the long clicks to pass through the widgetView LinearLayout add android:longClickable="true". (For ordinary clicks add android:clickable="true")
So widgetView becomes:
<LinearLayout
android:id="#+id/widgetView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:gravity="center"
android:longClickable="true">
</LinearLayout>

Using a Viewflipper with Gridview

I've created a calendar which works fine, using a GridView which has an OnClickListener.
Now I wrapped the two GridViews in a ViewFlipper. The ViewFlipper has an OnTouchListener which also works fine, I can change the view by using ontouch when dragging. The problem is though that I have to drag on the EMTPY space in the Activity in order to use the ViewFlipper. When I drag on the GridView, nothing happends at all. But I can click on the GridView for OnClickListener.
xml:
<ViewFlipper android:id="#+id/details"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<GridView
android:id="#+id/weeks"
android:numColumns="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="8">
</GridView>
<GridView
android:id="#+id/calendar"
android:numColumns="7"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</GridView>
</LinearLayout>
android code:
#Override
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
currentX = arg1.getX();
// going backwards: pushing stuff to the right
if (currentX - downXValue < -(arg0.getWidth()/3))
{
mdh.nextMonth();
calendar.add(Calendar.MONTH, 1);
currentMonth.setText(new SimpleDateFormat("MMMM yyyy").format(calendar.getTime()));
cAdapter.notifyDataSetChanged();
updateWeeks();
// Set the animation
vf.setInAnimation(arg0.getContext(), R.anim.push_left_in);
vf.setOutAnimation(arg0.getContext(), R.anim.push_left_out);
// Flip!
vf.showPrevious();
}
// going forwards: pushing stuff to the left
if (currentX - downXValue > arg0.getWidth()/3)
{
mdh.previousMonth();
calendar.add(Calendar.MONTH, -1);
currentMonth.setText(new SimpleDateFormat("MMMM yyyy").format(calendar.getTime()));
cAdapter.notifyDataSetChanged();
updateWeeks();
// Set the animation
vf.setInAnimation(arg0.getContext(), R.anim.push_right_in);
vf.setOutAnimation(arg0.getContext(), R.anim.push_right_out);
// Flip!
vf.showNext();
}
break;
}
gridview.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
return detector.onTouchEvent(event);
}
});
I had the same issue with a ViewFlipper and ScrollViews.
Try adding the onTouchListener to your GridView aswell and it should work.

Categories

Resources