0
votes

I've written a small activity that uses fragments with a ViewPager to show images.

I've also implemented a custom GestureListener to catch the swipe up and swipe down gestures without interferring with the ViewPager's own gesture handling. What I want to achieve is to show a layout when the user swipes down.

Problem is, I haven't found out how to execute the animation when the gesture listener detects the swipe down gesture.

EDIT: Added context and view to MyGestureListener to reference the view and context. Logging shows that the gesture is detected correctly and the view inside MyGestureListener is the correct one but nothing gets animated.

Code as follows.

Activity:

public class MainActivity extends FragmentActivity {

private GestureDetector gestureDetector;
private ViewPager vwpMain;
private PagerAdapter pgaMain;
private RelativeLayout layout;
private LinearLayout topLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    layout = (RelativeLayout) findViewById(R.id.container);
    topLayout = (LinearLayout) findViewById(R.id.topPanel);
    vwpMain = (ViewPager) findViewById(R.id.vwpMain);
    pgaMain = new MyPagerAdapter(getSupportFragmentManager());
    vwpMain.setAdapter(pgaMain);
    gestureDetector = new GestureDetector(this, new MyGestureListener(getApplicationContext(), topLayout));
    layout.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            gestureDetector.onTouchEvent(event);
            return true;
        }
    });
}

public boolean dispatchTouchEvent(MotionEvent ev) {
    super.dispatchTouchEvent(ev);
    return gestureDetector.onTouchEvent(ev);
}

private class MyPagerAdapter extends FragmentPagerAdapter {

    public MyPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int pos) {
        return ImageFragment.create(pos);
    }

    @SuppressLint("SdCardPath")
    @Override
    public int getCount() {
        File f = new File("/mnt/sdcard/FragmentImages/");
        return f.listFiles().length;
    }
}

Fragment:

public class ImageFragment extends Fragment {

private int pageNumber;
private ImageView i;

public static ImageFragment create(int pageNumber) {
    ImageFragment f = new ImageFragment();
    Bundle b = new Bundle();
    b.putInt("index", pageNumber);
    int indice = pageNumber + 1;
    String ruta = Environment.getExternalStorageDirectory().getPath()
            + "/FragmentImages/imagen_" + indice + ".jpg";
    b.putString("file", ruta);
    f.setArguments(b);
    return f;
}

public ImageFragment() {
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    pageNumber = getArguments().getInt("index");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // Inflate the layout containing a title and body text.
    ViewGroup rootView = (ViewGroup) inflater.inflate(
            R.layout.fragment_image, container, false);
    i = (ImageView) rootView.findViewById(R.id.imgImagen);
    BitmapWorkerTask task = new BitmapWorkerTask(i);
    task.execute(getArguments().getString("file"));
    return rootView;
}

public int getPageNumber() {
    return pageNumber;
}

public class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {

    private final WeakReference<ImageView> imageViewReference;
    private String data;

    public BitmapWorkerTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        data = params[0];
        return BitmapFactory.decodeFile(data);
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}
}

Gesture listener:

public class MyGestureListener extends SimpleOnGestureListener {

private static final int SWIPE_MIN_DISTANCE = 75;
private static final int SWIPE_MAX_OFF_PATH = 100;
private static final int SWIPE_THRESHOLD_VELOCITY = 50;

    public Context context;
public View view;

public MyGestureListener() {
    super();
            context = _context;
    view = _view;
}

@Override
public boolean onDown(MotionEvent event) {
    return true;
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
    float dX = e2.getX() - e1.getX();
    float dY = e1.getY() - e2.getY();
    if (Math.abs(dY) < SWIPE_MAX_OFF_PATH
            && Math.abs(velocityX) >= SWIPE_THRESHOLD_VELOCITY
            && Math.abs(dX) >= SWIPE_MIN_DISTANCE) {
        if (dX > 0) {
            Log.d("Fragment", "Swiping right");
        } else {
            Log.d("Fragment", "Swiping left");
        }
    } else if (Math.abs(dX) < SWIPE_MAX_OFF_PATH
            && Math.abs(velocityY) >= SWIPE_THRESHOLD_VELOCITY
            && Math.abs(dY) >= SWIPE_MIN_DISTANCE) {
        if (dY > 0) {
            Log.d("Fragment", "Swiping up");
        } else {
            Log.d("Fragment", "Swiping down");
                            Animation a = AnimationUtils.loadAnimation(context, R.anim.show_top);
            Log.d("Fragment", view.toString());
            view.startAnimation(a);
        }
    }
    return false;
}
}

Layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<LinearLayout
    android:id="@+id/topPanel"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="horizontal"
    android:visibility="gone" >

    <TextView
        android:id="@+id/topPanelTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/topPanelText"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@android:color/black" />
</LinearLayout>

<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/vwpMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</RelativeLayout>

Animation:

<?xml version="1.0" encoding="utf-8"?>

<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromYDelta="-100%"
    android:toYDelta="0%" >
</translate>

1
What is the error shown by Eclipse if you start your animation there: Log.d("Fragment", "Swiping down");znat
You should show the error first. I had some animation problem once and as I remember posting a runnable on handler was a solution for it. Try to make a handler = new Handler() in onCreate. And post (handler.post()) a runnable starting the animation on it.Mark
Animation a = AnimationUtils.loadAnimation(this, R.anim.show_top); shows The method loadAnimation(Context, int) in the type AnimationUtils is not applicable for the arguments (MyGestureListener, int)Léster

1 Answers

0
votes

Found a solution. I changed the swiping down detection code to this:

Log.d("Fragment", "Swiping down");
Animation showTopPanel = AnimationUtils.loadAnimation(context, R.anim.show_top);
topView.bringToFront();
topView.setVisibility(View.VISIBLE);
topView.startAnimation(showTopPanel);

Then the animation showed correctly.