I am working on multi finger gestures, I tried using Google gesture builder but it will not support for multi finger gestures, How to recognize two finger V shape gesture in android.?
I'm sure you can use a ScaleGestureDetector for this.
After all a "V" from the top is just a pinch with some translation on the Y axis.
So I think you can analyse the focus point and scale factor to determine a "V" has taken place.
Here is a working example. In the end I didn't need to look at the scale. There are a couple of sensitivity values you can adjust such as the range of acceptable angles and the ratio of Y to X movement.
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.TextView;
public class MainActivity extends Activity {
public static class VListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
private float initialFocusX;
private float initialFocusY;
#Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.d(TAG, String.format("%.2f,%.2f s:%.2f", detector.getFocusX(),
detector.getFocusY(), detector.getScaleFactor()));
initialFocusX = detector.getFocusX();
initialFocusY = detector.getFocusY();
return true;
}
#Override
public void onScaleEnd(ScaleGestureDetector detector) {
float deltaX = detector.getFocusX() - initialFocusX;
float deltaY = detector.getFocusY() - initialFocusY;
if (deltaY == 0) {
Log.d(TAG, "Not a V, no Y movement");
onNonV();
return;
}
float yMovementRatio = Math.abs(deltaY / deltaX);
if (yMovementRatio < 4) {
Log.d(TAG,
String.format(
"Not a V, the ratio of Y movement to X was not high enough: %.2f",
yMovementRatio));
onNonV();
return;
}
float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX));
if (angle > 80 && angle < 100) {
Log.d(TAG, "V!");
onV();
return;
} else {
Log.d(TAG,
String.format(
"Not a V, the angle shows the V was drawn in the wrong direction: %.2f",
angle));
onNonV();
}
}
protected void onV() {
}
protected void onNonV() {
}
}
protected static final String TAG = "MainActivity";
private ScaleGestureDetector mScaleGestureDetector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView t = (TextView) findViewById(R.id.vTextIndicator);
mScaleGestureDetector = new ScaleGestureDetector(this, new VListener() {
#Override
protected void onV() {
t.setText("V!");
}
#Override
protected void onNonV() {
t.setText("Non V");
}
});
}
public boolean onTouchEvent(MotionEvent event) {
boolean retVal = mScaleGestureDetector.onTouchEvent(event);
return retVal || super.onTouchEvent(event);
}
}
activity_main.xml Layout is just:
<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" >
<TextView
android:id="#+id/vTextIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
Sample app - InteractiveChart.zip
This links might help - Draggin & Scaling and Handling Multi-Touch Gestures
Related
My problem is closely related to two other questions that haven't been answered yet.
ViewPager not responding to touch in layout area created dynamically in Fragment
https://stackoverflow.com/questions/53469581/problem-with-vertical-viewpager-like-inshorts
My Vertical ViewPager works wonderfully and consistently within any device I have tested and with any OS 5 - 8. I recently upgraded a pixel 2XL with Android Pie and now my Vertical ViewPager appears to be unresponsive, then works, then it acts like it loses focus, then works. Drag a page and it moves and snaps back to original position. Or just bounces back. Again, similar to the other two questions linked above.
Prior to Android 9, vertical scrolling and paging is perfect. I've tried using reflection with a little success. It will swipe better and doesn't seem to lose focus as much. But if I try swiping with my other hand it stops, or if I change my placement of where I am swiping it will stop. This is very perplexing. I have added all the code required to replicate this issue on a device running Android 9.
The Activity
public class FullscreenActivity extends AppCompatActivity {
VerticalViewPager verticalViewPager;
FragmentStatePagerExample fragmentStatePagerExample;
int pagerPadding;
/**
* Whether or not the system UI should be auto-hidden after
* {#link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
*/
private static final boolean AUTO_HIDE = true;
/**
* If {#link #AUTO_HIDE} is set, the number of milliseconds to wait after
* user interaction before hiding the system UI.
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* Some older devices needs a small delay between UI widget updates
* and a change of the status and navigation bar.
*/
private static final int UI_ANIMATION_DELAY = 300;
private final Handler mHideHandler = new Handler();
private FrameLayout mContentView;
private final Runnable mHidePart2Runnable = new Runnable() {
#SuppressLint("InlinedApi")
#Override
public void run() {
// Delayed removal of status and navigation bar
// Note that some of these constants are new as of API 16 (Jelly Bean)
// and API 19 (KitKat). It is safe to use them, as they are inlined
// at compile-time and do nothing on earlier devices.
verticalViewPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
};
private View mControlsView;
private final Runnable mShowPart2Runnable = new Runnable() {
#Override
public void run() {
// Delayed display of UI elements
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.show();
}
mControlsView.setVisibility(View.VISIBLE);
}
};
private boolean mVisible;
private final Runnable mHideRunnable = new Runnable() {
#Override
public void run() {
hide();
}
};
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
pagerPadding = getScreenDimension(this);
mVisible = true;
mControlsView = findViewById(R.id.fullscreen_content_controls);
verticalViewPager = findViewById(R.id.main_viewpager);
verticalViewPager.setPadding(0,0,0,pagerPadding);
verticalViewPager.setClipToPadding(false);
fragmentStatePagerExample = new FragmentStatePagerExample(getSupportFragmentManager());
verticalViewPager.setAdapter(fragmentStatePagerExample);
verticalViewPager.setCurrentItem(0);
// Set up the user interaction to manually show or hide the system UI.
verticalViewPager.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggle();
}
});
// Upon interacting with UI controls, delay any scheduled hide()
// operations to prevent the jarring behavior of controls going away
// while interacting with the UI.
findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
delayedHide(100);
}
private void toggle() {
if (mVisible) {
hide();
} else {
show();
}
}
private void hide() {
// Hide UI first
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
mControlsView.setVisibility(View.GONE);
mVisible = false;
// Schedule a runnable to remove the status and navigation bar after a delay
mHideHandler.removeCallbacks(mShowPart2Runnable);
mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
}
#SuppressLint("InlinedApi")
private void show() {
// Show the system bar
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mVisible = true;
// Schedule a runnable to display UI elements after a delay
mHideHandler.removeCallbacks(mHidePart2Runnable);
mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
}
/**
* Schedules a call to hide() in delay milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
private static int getScreenDimension(Context context)
{
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
return (int)Math.round(height * .2);
}
}
The Fragment
public class ImageFragment extends Fragment{
ImageView imageView;
String imageUrl = "";
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Bundle bundle = getArguments();
imageUrl = bundle.getString("url");
return inflater.inflate(R.layout.fragment_image, container,false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
imageView = (ImageView)view.findViewById(R.id.iv_imagefragment);
Glide.with(getActivity()).load(imageUrl).into(imageView);
}
public static Fragment getInstance(int position, String url){
Bundle bundle = new Bundle();
bundle.putString("url",url);
ImageFragment fragment = new ImageFragment();
fragment.setArguments(bundle);
return fragment;
}
}
The ViewPager
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
setOffscreenPageLimit(2);
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
The ViewPager Adapter
public class FragmentStatePagerExample extends FragmentStatePagerAdapter {
String url = "";
public FragmentStatePagerExample(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
url = "https://images.unsplash.com/photo-1532977692289-827d858a170b?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=29b1d5377ad9db8de64b1b73d21812c7&auto=format&fit=crop&w=1474&q=80";
return ImageFragment.getInstance(position,url);
case 1:
url = "https://images.unsplash.com/photo-1533029516911-0458c644baea?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0f618e036e338f48ef919b8fb86c5ba1&auto=format&fit=crop&w=701&q=80";
return ImageFragment.getInstance(position,url);
case 2:
url = "https://images.unsplash.com/photo-1532989622000-d4f013a215e1?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=1a69643c04176376315714b9b2897de5&auto=format&fit=crop&w=677&q=80";
return ImageFragment.getInstance(position,url);
default:
url = "https://images.unsplash.com/photo-1532983819500-85d633c73b7a?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=1f0b228b67f03064241534a6c65d9497&auto=format&fit=crop&w=1050&q=80";
return ImageFragment.getInstance(position,url);
}
}
#Override
public int getCount() {
return 4;
}
}
Activity XML
<FrameLayout 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="#0099cc"
tools:context=".FullscreenActivity">
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<com.david.verticalviewpagerexample.VerticalViewPager
android:id="#+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="#+id/fullscreen_content_controls"
style="?metaButtonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="#color/black_overlay"
android:orientation="horizontal"
tools:ignore="UselessParent">
<Button
android:id="#+id/dummy_button"
style="?metaButtonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/dummy_button" />
</LinearLayout>
</FrameLayout>
Fragment XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_imagefragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
</LinearLayout>
Update : 1
https://github.com/youngkaaa/YViewPagerDemo
There is another library and that works really smooth on Android Pie, but it has few soft crashes. Also, it crashes on API 19.
Update : 2
Google has recently released ViewPager2 with androidx support library https://developer.android.com/jetpack/androidx/releases/viewpager2, that supports vertical viewpager. However, it is still in alpha version and it has many known issues.
After spending hell amount of time on SO, trying many GitHub
libraries and waiting for someone to respond on the bounty,
then I came up with below solutions and hope that it helps whoever needs it.
At first, this question got my attention and I think most of the answers over there are helpful, hence I upvoted them.
The main answer which helped me are link-1 and link-2.
Even though I have to make a few minor changes to ignore horizontal swipe
fling events.
Please do try this code and provide your feedback for any further improvements, thanks in advance. Happy Coding :)
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class VerticalViewPager extends ViewPager {
float x = 0;
float mStartDragX = 0;
private static final float SWIPE_X_MIN_THRESHOLD = 50; // Decide this magical nuber as per your requirement
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (getAdapter() != null) {
if (getCurrentItem() >= 0 || getCurrentItem() < getAdapter().getCount()) {
swapXY(event);
final int action = event.getAction();
switch (action & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
mStartDragX = event.getX();
if (x < mStartDragX
&& (mStartDragX - x > SWIPE_X_MIN_THRESHOLD)
&& getCurrentItem() > 0) {
Log.i("VerticalViewPager", "down " + x + " : " + mStartDragX + " : " + (mStartDragX - x));
setCurrentItem(getCurrentItem() - 1, true);
return true;
} else if (x > mStartDragX
&& (x - mStartDragX > SWIPE_X_MIN_THRESHOLD)
&& getCurrentItem() < getAdapter().getCount() - 1) {
Log.i("VerticalViewPager", "up " + x + " : " + mStartDragX + " : " + (x - mStartDragX));
mStartDragX = 0;
setCurrentItem(getCurrentItem() + 1, true);
return true;
}
break;
}
} else {
mStartDragX = 0;
}
swapXY(event);
return super.onTouchEvent(swapXY(event));
}
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercepted = super.onInterceptTouchEvent(swapXY(event));
switch (event.getAction() & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
break;
}
swapXY(event); // return touch coordinates to original reference frame for any child views
return intercepted;
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
private class VerticalPageTransformer implements PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
}
You can try this lib:
VerticalViewPager, this works fine on my project.
But this lib is copied from v19, so some methods will not exist, you can implement yourself.
The problem seems to be in the way #swapXY exchanges the x and y values. I believe that the VelocityTracker used in ViewPager uses #getAxisValue and not #getX/#getY, and the result is not swapped. But there doesn't seem to be a way to set the axis values nor to subclass MotionEvent so I didn't find a way to stick with the simple #swapXY solution. I forked ViewPager and use VelocityTracker.getYVelocity when I detect the unswapped condition.
diff --git project/src/main/java/org/gc/project/util/ShopVerticalViewPager.java project/src/main/java/org/gc/project/util/ShopVerticalViewPager.java
index e5560a0..f23f9f7 100644
--- project/src/main/java/org/gc/project/util/MyVerticalViewPager.java
+++ project/src/main/java/org/gc/project/util/MyVerticalViewPager.java
## -179,4 +179,8 ## public class ShopVerticalViewPager extends ViewPager {
return super.onTouchEvent( swapXY( ev ) );
}
+ public boolean isVerticalMode() {
+ return true;
+ }
+
}
\ No newline at end of file
diff --git project/src/main/java/gcandroid/support/v4/view/ViewPager.java project/src/main/java/gcandroid/support/v4/view/ViewPager.java
index 20e1448..4ae2d3c 100644
--- project/src/main/java/gcandroid/support/v4/view/ViewPager.java
+++ project/src/main/java/gcandroid/support/v4/view/ViewPager.java
## -205,6 +205,7 ## public class ViewPager extends ViewGroup {
private int mMaximumVelocity;
private int mFlingDistance;
private int mCloseEnough;
+ private boolean mInvertedVelocityTrackerInVerticalMode = false;
// If the pager is at least this close to its final position, complete the scroll
// on touch down and let the user interact with the content inside instead of
## -391,6 +392,21 ## public class ViewPager extends ViewGroup {
ViewCompat.setImportantForAccessibility(this,
ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
+
+ // tell if the velocity tracker is inverted in vertical mode (most probably uses MotionEvent.getAxisValue instead of MotionEvent.getX but
+ // I can't change these values nor inherit from MotionEvent)
+ VelocityTracker vt = VelocityTracker.obtain();
+ long time = SystemClock.uptimeMillis();
+ MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0);
+ vt.addMovement(ev);
+ ev.recycle();
+ ev = MotionEvent.obtain(time, time + 10, MotionEvent.ACTION_MOVE, 10, 0, 0);
+ ev.setLocation( 0, 10 );
+ vt.addMovement(ev);
+ ev.recycle();
+ vt.computeCurrentVelocity(1000, mMaximumVelocity);
+ mInvertedVelocityTrackerInVerticalMode = vt.getYVelocity() == 0;
+ vt.recycle();
}
#Override
## -2027,6 +2043,10 ## public class ViewPager extends ViewGroup {
return mIsBeingDragged;
}
+ public boolean isVerticalMode() {
+ return false;
+ }
+
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (mFakeDragging) {
## -2111,8 +2131,9 ## public class ViewPager extends ViewGroup {
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(
- velocityTracker, mActivePointerId);
+ int initialVelocity = (int) ( isVerticalMode() && mInvertedVelocityTrackerInVerticalMode ? VelocityTrackerCompat.getYVelocity( velocityTracker, mActivePointerId )
+ : VelocityTrackerCompat.getXVelocity( velocityTracker, mActivePointerId ) );
+
mPopulatePending = true;
final int width = getClientWidth();
final int scrollX = getScrollX();
link check this news app, i want to develop like this.
i want swipe up/down side effect..
i tried this code,but not correctly swiping as i want.
in this code when i swipe up/down,only the text is changing not a layout.
public class ArticlesActivity extends Activity implements GestureDetector.OnGestureListener{
ImageView image,imageArticle;
TextView tv1,tv2,tv3;
private GestureDetector gd;
LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_articles);
//Creating GestureDetector Object
gd = new GestureDetector(this, this);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
//Registering TouchEvent with GestureDetector
return gd.onTouchEvent(event);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
//Destroying Activity
finish();
}
#Override
public boolean onDown(MotionEvent arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// TODO Auto-generated method stub
//Defining Sensitivity
float sensitivity = 50;
//Swipe Up Check
if(e1.getY() - e2.getY() > sensitivity){
//Setting Image Resource to Up_Arrow on Swipe Up
tv1.setText("Some Text");
tv2.setText("Some Text");
tv3.setText("Some Text");
image.setImageResource(R.drawable.logo);
imageArticle.setImageResource(R.drawable.ic_launcher);
return true;
}
//Swipe Down Check
else if(e2.getY() - e1.getY() > sensitivity){
//Setting Image Resource to Down_Arrow on Swipe Down
tv1.setText("Some Text");
tv2.setText("Some Text");
tv3.setText("Some Text");
image.setImageResource(R.drawable.ic_launcher);
imageArticle.setImageResource(R.drawable.logo);
return true;
}
else{
//If some error occurrs, setting again to Default_Image (Actually it will never happen in this case)
image.setImageResource(R.drawable.logo);
return true;
}
}
#Override
public void onLongPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onShowPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean onSingleTapUp(MotionEvent arg0) {
// TODO Auto-generated method stub
return false;
}
}
This will work like inshorts app
main.xml
<com.cardviewanimation.VerticalViewPager
android:id="#+id/verticleViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardCornerRadius="2dp"
card_view:contentPadding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="#drawable/background"
android:scaleType="fitXY"/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
VerticleViewPagerActivity.java
public class VerticleViewPagerActivity extends AppCompatActivity {
VerticalViewPager verticalViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
verticalViewPager = (VerticalViewPager) findViewById(R.id.verticleViewPager);
verticalViewPager.setAdapter(new VerticlePagerAdapter(this));
}
}
VerticlePagerAdapter.java
public class VerticlePagerAdapter extends PagerAdapter {
String mResources[] = {"To start off lets understand what exactly Android CardView is? Its a new widget for Android, which can be used to display a card sort of a layout in android. As you may know Android material design is inspired from paper and ink concept. Mostly it displays views on top of each other, with shadows. In simple terms, Android CardView is such a view which has all material design properties, most importantly showing shadows according the elevation. The best part about this view is that it extends FrameLayout and it can be displayed on all the platforms of android since it’s available through the Support v7 library. Lets have a look at some of its properties:","To start off lets understand what exactly Android CardView is? Its a new widget for Android, which can be used to display a card sort of a layout in android. As you may know Android material design is inspired from paper and ink concept. Mostly it displays views on top of each other, with shadows. In simple terms, Android CardView is such a view which has all material design properties, most importantly showing shadows according the elevation. The best part about this view is that it extends FrameLayout and it can be displayed on all the platforms of android since it’s available through the Support v7 library. Lets have a look at some of its properties:"};
Context mContext;
LayoutInflater mLayoutInflater;
public VerticlePagerAdapter(Context context) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mResources.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mLayoutInflater.inflate(R.layout.content_main, container, false);
TextView label = (TextView) itemView.findViewById(R.id.textView);
label.setText(mResources[position]);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
VerticalViewPager.java
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // [0,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
I got the solution for your problem as inshorts app using vertical view pager. I am sharing some code that can serve your purpose.
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
this(context, null);
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setPageTransformer(false, new DefaultTransformer());
}
private MotionEvent swapTouchEvent(MotionEvent event) {
float width = getWidth();
float height = getHeight();
float swappedX = (event.getY() / height) * width;
float swappedY = (event.getX() / width) * height;
event.setLocation(swappedX, swappedY);
return event;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercept = super.onInterceptTouchEvent(swapTouchEvent(event));
//If not intercept, touch event should not be swapped.
swapTouchEvent(event);
return intercept;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapTouchEvent(ev));
}
}
As you can see the class above uses the DefaultTransformer class for transformation which implement ViewPager.PageTransformer for custom animation this class code is given below
public class DefaultTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
float alpha = 0;
if (0 <= position && position <= 1) {
alpha = 1 - position;
} else if (-1 < position && position < 0) {
alpha = position + 1;
}
System.out.println("alpha--" + alpha);
view.setAlpha(alpha);
System.out.println("position--" + position);
System.out.println("view.getWidth()--" + view.getWidth());
view.setTranslationX(view.getWidth() * -position);
float yPosition = position * view.getHeight();
System.out.println("yPosition---"+yPosition);
view.setTranslationY(yPosition);
}
}
and my activity code is like this
public class SwipeUpActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe_layout);
setTitle("");
initViewPager();
}
private void initViewPager() {
VerticalViewPager viewPager = (VerticalViewPager) findViewById(R.id.vertical_viewpager);
//viewPager.setPageTransformer(false, new ZoomOutTransformer());
//viewPager.setPageTransformer(true, new StackTransformer());
String title = "ContentFragment";
viewPager.setAdapter(new ContentFragmentAdapter.Holder(getSupportFragmentManager())
.add(ContentFragment.newInstance(title, 1))
.add(ContentFragment.newInstance(title, 2))
.add(ContentFragment.newInstance(title, 3))
.add(ContentFragment.newInstance(title, 4))
.add(ContentFragment.newInstance(title, 5))
.set());
//If you setting other scroll mode, the scrolled fade is shown from either side of display.
viewPager.setOverScrollMode(View.OVER_SCROLL_NEVER);
}
The layout named activity_swipe_layout is like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#A6000000"
android:layout_height="match_parent">
<gmaillogindemo.com.irk.transforms.VerticalViewPager
android:id="#+id/vertical_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and the result is looking like this:
after swipe up
I am creating images in which when scrolled up, the image should get enlarged and remaining images should get smaller. Similarly when second image pushed up, it should enlarge and show. I used accordion type but nothing works. I searched but couldn't find.
In IPhone, it has features but I couldn't find how to create for android. This is for
same effect to be implemented in android.
I used ScaleAnimation with hide and show of layouts to open where image been placed inside the layout. But that also didn't work.
if(openLayout == panel1){
panel1.startAnimation(new ScaleAnimToHide(1.0f, 1.0f, 1.0f, 0.0f, 200, panel1, true));
}
Can someone help me to solve this issue?
Thanks in advance!!
I have created a basic custom view which replicates this behaviour, it's not completely the same but I think it's close enough for now, if it needs to be exactly the same this can be quickly achieved by modifying the updateChildViews() method. I wrote this class in 20 minutes so it's far from perfect, for a production ready solution some additional work has to be done. Generally this solution works with all kinds of child views, but to replicate the exact behaviour use an ImageView as background for your child views and set this property on the ImageViews:
android:scaleType="centerCrop"
Problems I see with my solution in it's current state:
Only works in vertical orientation
No view recycling.
Should be derived from AdapterView and not LinearLayout.
Anyway that's how it looks so far:
Here is the source code:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
public class Accordion extends LinearLayout {
private static final String LOG_TAG = Accordion.class.getSimpleName();
private double scrollProgress = 0.0;
private double topViewScaleFactor = 2.0;
private double collapsedViewHeight = 200.0;
private double expandedViewHeight = 700.0;
private double scrollProgressPerView = expandedViewHeight;
private final ScrollTouchListener touchListener = new ScrollTouchListener() {
#Override
protected void onScroll(float x, float y) {
scrollProgress += y;
if(scrollProgress < 0.0) {
scrollProgress = 0.0;
}
int viewCount = getChildCount();
double maxScrollProgress = (viewCount - 1) * scrollProgressPerView + 1;
if(scrollProgress > maxScrollProgress) {
scrollProgress = maxScrollProgress;
}
Log.i(LOG_TAG, String.format("Scroll Progress: %f", scrollProgress));
updateChildViews();
}
};
public Accordion(Context context) {
super(context);
this.setOnTouchListener(this.touchListener);
}
public Accordion(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnTouchListener(this.touchListener);
}
public Accordion(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setOnTouchListener(this.touchListener);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
updateChildViews();
}
private void updateChildViews() {
int viewCount = getChildCount();
double progress = scrollProgress;
double overflow = 0;
for(int i = 0; i < viewCount; i++) {
View child = getChildAt(i);
if(child != null) {
if(progress >= scrollProgressPerView) {
progress -= scrollProgressPerView;
child.setVisibility(View.GONE);
setChildHeight(child, 0);
} else if (progress > 0) {
setChildHeight(child, expandedViewHeight - progress);
overflow = progress;
child.setVisibility(View.VISIBLE);
progress = 0;
} else {
if(overflow > 0) {
double height = collapsedViewHeight + overflow;
if(height > expandedViewHeight) {
height = expandedViewHeight;
}
setChildHeight(child, height);
overflow = 0;
} else {
setChildHeight(child, i > 0 ? collapsedViewHeight : expandedViewHeight);
}
child.setVisibility(View.VISIBLE);
}
}
}
}
private void setChildHeight(View child, double height) {
child.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int)height));
}
private static abstract class ScrollTouchListener implements OnTouchListener {
private static final String LOG_TAG = ScrollTouchListener.class.getSimpleName();
private boolean scrolling = false;
private float x = 0;
private float y = 0;
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
scrolling = true;
return true;
case MotionEvent.ACTION_UP:
scrolling = false;
return true;
case MotionEvent.ACTION_MOVE:
if (scrolling) {
float newX = event.getX();
float newY = event.getY();
float difX = x - newX;
float difY = y - newY;
onScroll(difX, difY);
x = newX;
y = newY;
}
return true;
default:
return false;
}
}
protected abstract void onScroll(float x, float y);
}
}
To use it just put it in a layout like this:
<at.test.app.Accordion xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/alpen"/>
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/alpen"/>
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/alpen"/>
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/alpen"/>
</at.test.app.Accordion>
If you have any additional questions feel free to ask!
I think if the container you are using is a ListView, then following must be useful.Just need to detect the center element of the list view, and apply the zooming effect to the image in that row.Following is the code that can be used to implement this strategy:
int visibleChildCount = (listView1.getLastVisiblePosition() - listView1.getFirstVisiblePosition()) + 1;
In your getView() method:
if(position==visibleChildCount/2)
{
//Center Element
//Apply the Transition Effect From the XML files to the Image to Grow.
}
I'm still fairly new to android and I'm currently trying to create pong.
At the moment I am trying to animate two images, one is pong's ball and the second is the paddle. Right now I have those two images and I've got them animating. The ball behaves like I want it to bouncing around the x and y axis and I have the paddle sliding back and forth across the x axis but for some reason the paddle behaves weirdly.
The paddle for some reason animates choppy, stopping and starting whenever it wants. But whenever I remove the ball animation from the code the paddle acts and behaves like I intended it to
If anyone has any suggestion for what I am doing wrong or overlooking, I am all ears, Thanks!
package com.example.pongtest;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.app.Activity;
public class MainActivity extends Activity {
LinearLayout lay1;
ImageView ballImg, paddleImg;
TimerTask thisTimerTask;
Timer thisTimer;
LinearLayout.LayoutParams params;
float ballPosX=10;
float ballPosY=10;
float paddlePosX=200;
float paddlePosY=10;
float ballOnLeftWall=0;
float ballOnRightWall=270;
float ballOnBottomWall=400;
float ballOnTopWall=0;
float paddleOnLeftWall=0;
float paddleOnRightWall=200;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lay1 = new LinearLayout(this);
ballImg = new ImageView(this);
ballImg.setBackgroundResource(R.drawable.circlewdot);
setPosition(0,0,50,50);
ballImg.setLayoutParams(params);
paddleImg=new ImageView(this);
paddleImg.setBackgroundResource(R.drawable.paddle);
setPosition(0,0,50,10);
paddleImg.setLayoutParams(params);
lay1.addView(ballImg);
lay1.addView(paddleImg);
setContentView(lay1);
thisTimerTask = new ThisTimerClass();
thisTimer = new Timer();
//setup frame rate of timer
thisTimer.scheduleAtFixedRate(thisTimerTask, 2000, 16);
}
public void setPosition(float x, float y, float width, float height) {
params = new LinearLayout.LayoutParams(0,0);
params.topMargin = (int)y;
params.leftMargin = (int)x;
params.width = (int)width;
params.height = (int)height;
}
class ThisTimerClass extends TimerTask {
boolean directionOfBall_isRight = true;
boolean directionOfBall_isDown = true;
boolean directionOfPaddle_isLeft = true;
#Override
public void run() {
// Will be called each time the timer is fired.
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
setPosition(ballPosX,ballPosY,50,50);
ballImg.setLayoutParams(params);
setPosition(paddlePosX,paddlePosY,50,10);
paddleImg.setLayoutParams(params);
//animates ball across the screen
if (directionOfBall_isRight == true)
{ballPosX = (ballPosX + 1);}
else if (directionOfBall_isRight == false)
{ballPosX = (ballPosX - 1);}
if (directionOfBall_isDown == true)
{ballPosY = (ballPosY + 1);}
else if (directionOfBall_isDown == false)
{ballPosY = (ballPosY - 1);}
//redirects ball
if (ballPosX > ballOnRightWall)
{directionOfBall_isRight = false;}
else if (ballPosX < ballOnLeftWall)
{directionOfBall_isRight = true;}
if (ballPosY > ballOnBottomWall)
{directionOfBall_isDown = false;}
else if (ballPosY < ballOnTopWall)
{directionOfBall_isDown = true;}
//animates paddle across the screen
if (directionOfPaddle_isLeft == true)
{paddlePosX = (paddlePosX - 1);}
else if (directionOfPaddle_isLeft == false)
{paddlePosX = (paddlePosX + 1);}
//redirects paddle
if (paddlePosX < paddleOnLeftWall)
{directionOfPaddle_isLeft = false;}
else if (paddlePosX > paddleOnRightWall)
{directionOfPaddle_isLeft = true;}
}
});
}
}
}
this is possibly because you are controlling the ball and the paddle on the same thread. the system can't concurrently do two things from a single thread!
I'd like to use ImageViewZoom with Universal Image Loader in ImagePagerActivity.
I am able to zoom the image, Swipe to the next image. But i am facing problem when image is in Zoom position.
if an image is zoomed and i am at center position, if i want to see the right side part of the same image and swipe left it is going to the next image. Please help me in doing this.
here is my XML code:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="1dip" >
<it.sephiroth.android.library.imagezoom.ImageViewTouch
android:layout_weight="1"
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter" />
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
EDIT:
Thank you NOSTRA, Now i am able to control the zoom and slide with the below code. But the problem with Multi touch zoom. I am not able to zoom with two fingers.
Here is my previous code(working fine with two finger):
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale( ScaleGestureDetector detector ) {
Log.d( LOG_TAG, "onScale" );
float span = detector.getCurrentSpan() - detector.getPreviousSpan();
float targetScale = mCurrentScaleFactor * detector.getScaleFactor();
if ( mScaleEnabled ) {
targetScale = Math.min( getMaxZoom(), Math.max( targetScale, getMinZoom()-0.1f ) );
zoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );
mCurrentScaleFactor = Math.min( getMaxZoom(), Math.max( targetScale, getMinZoom()-1.0f ) );
mDoubleTapDirection = 1;
invalidate();
return true;
}
return false;
}
}
And here is the Modified one:
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
externalScaleListener.onScaleBegin();
return super.onScaleBegin(detector);
}
#Override
public void onScaleEnd(ScaleGestureDetector detector) {
externalScaleListener.onScaleEnd(mCurrentScaleFactor);
}
}
First you must be able to listen scaling of image. ImageViewTouch doesn't support this feature (e.g gesture-imageview support it) so you should implement it yourself.
Change ImageViewTouch.java like this:
public class ImageViewTouch extends ImageViewTouchBase {
...
private OnPageScaleListener externalScaleListener;
public void setOnScaleListener(OnPageScaleListener onScaleListener) {
this.externalScaleListener = onScaleListener;
}
public interface OnPageScaleListener {
void onScaleBegin();
void onScaleEnd(float scale);
}
#Override
protected void onZoom(float scale) {
super.onZoom(scale);
if (!mScaleDetector.isInProgress()) {
mCurrentScaleFactor = scale;
externalScaleListener.onScaleEnd(scale);
}
}
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
externalScaleListener.onScaleBegin();
return super.onScaleBegin(detector);
}
...
#Override
public void onScaleEnd(ScaleGestureDetector detector) {
externalScaleListener.onScaleEnd(mCurrentScaleFactor);
}
}
...
}
Then use next implementation of ViewPager in your application:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* {#link ViewPager} which can be deactivated (ignore touch events)
*
* #author Sergey Tarasevich
* #created 19.07.2012
*/
public class DeactivableViewPager extends ViewPager {
private boolean activated = true;
public DeactivableViewPager(Context context) {
super(context);
}
public DeactivableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void activate() {
activated = true;
}
public void deactivate() {
activated = false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (activated) {
try {
return super.onInterceptTouchEvent(event);
} catch (Exception e) { // sometimes happens
return true;
}
} else {
return false;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
try {
return super.onTouchEvent(event);
} catch (Exception e) {
return true;
}
}
}
Then in your ViewPager's adapter you should set next scale listener for your ImageViewTouch:
ImageViewTouch imageView = ...;
imageView.setOnScaleListener(new OnPageScaleListener() {
#Override
public void onScaleBegin() {
viewPager.deactivate();
}
#Override
public void onScaleEnd(float scale) {
if (scale > 1.0) {
viewPager.deactivate();
} else {
viewPager.activate();
}
}
});
imageLoader.displayImage(url, imageView, ...);
And don't forget set big values for maxImage***ForMemoryCache in ImageLoader's configuration so UIL won't downscale original images during decoding to Bitmaps:
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
...
.memoryCacheExtraOptions(3000, 3000)
...
.build();
I was having trouble with pre-zoomed images in viewPager, but now its alright and solved the problem.
You have to search the ImageViewTouchBase class for this line:
protected DisplayType mScaleType = DisplayType.NONE;
then change it to:
protected DisplayType mScaleType = DisplayType.FIT_TO_SCREEN;
By default, DisplayType is set to NONE, its simple, just use FIT_TO_SCREEN and your images will be in the default size when sliding in viewPager.
Cheers
You can set those properties to make image fit to screen always
<it.sephiroth.android.library.imagezoom.ImageViewTouch
android:id="#+id/iv_pager_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:contentDescription="#string/descr_image"
android:scaleType="matrix" />