0

处理ExpandableListView并使用SwipetoDismissNOA来检测元素上的滑动手势listView,我想自定义此代码,因此当我对子元素执行滑动操作时 - (它们FrameLayout内部有两个布局) -上面的视图只是走出屏幕和下方视图按钮变为可见,并通过向上方视图的其他方向滑动再次返回。

你们能帮帮我吗?

4

1 回答 1

0

我会根据需要以某种方式对其进行更改,因此希望它也对您有用。

我将它与列表片段一起使用,您可以使用您想要的方式。

 package com.example.android.swipedismiss;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;

 import android.content.Context;
 import android.os.Bundle;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.ListFragment;
 import android.util.Log;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.BaseAdapter;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.Toast;

 public class fragmentActivity extends FragmentActivity {
// static ArrayAdapter<String> mAdapter;
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    gestureDetector = new GestureDetector(this, new MyGestureDetector());
    gestureListener = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    };

    FragmentManager fm = getSupportFragmentManager();

    if (fm.findFragmentById(android.R.id.content) == null) {
        MyListFragment1 list = new MyListFragment1();
        fm.beginTransaction().add(android.R.id.content, list).commit();
    }
}

public static class MyListFragment1 extends ListFragment {


    public class MyListAdapter extends BaseAdapter {
        String[] month;
        Context myContext;
        int ints = -1;
        public void remove(int position) {
            // TODO Auto-generated method stub
            // getItem(get)

            if (ints == -1) {
                ints = position;
            } else if (position != ints) {
                ints = position;
            } else {
                ints = -1;
            }

            myListAdapter.notifyDataSetChanged();

        }

        private void permanentDelete(int position) {
            List<String> list = new ArrayList<String>(Arrays.asList(month));
            list.remove(position);
            month = list.toArray(new String[0]);
            myListAdapter.notifyDataSetChanged();
        }

        public MyListAdapter(Context context, int textViewResourceId, String[] objects) {
            super();
            month = objects;
            myContext = context;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Log.e("getView", "Here " + month[position]);

            LayoutInflater inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View row = null;
            // for (int i = 0; i < month.length; i++) {
            if (position != ints) {

                row = inflater.inflate(R.layout.row, parent, false);
                TextView label = (TextView) row.findViewById(R.id.month);
                label.setText(month[position]);
                ImageView icon = (ImageView) row.findViewById(R.id.icon);

                // Customize your icon here
                icon.setImageResource(R.drawable.icon);
            } else {

                row = inflater.inflate(R.layout.after_swipe, parent, false);

                Button undo = (Button) row.findViewById(R.id.undo);
                Button action1 = (Button) row.findViewById(R.id.action_one);
                Button action2 = (Button) row.findViewById(R.id.action_two);
                undo.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        ints = -1;
                        myListAdapter.notifyDataSetChanged();
                    }
                });
                action1.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        Toast.makeText(getActivity().getApplicationContext(), "In Action 1", Toast.LENGTH_SHORT).show();

                    }
                });
                action2.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        Toast.makeText(getActivity().getApplicationContext(), "In Action 2", Toast.LENGTH_SHORT).show();

                    }
                });

            }
            // }

            Log.e("Selected Item", "Item" + ints);

            return row;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return month.length;
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

    }

    String[] month = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
    MyListAdapter myListAdapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        ListView listView = getListView();
        SwipeDismissListViewTouchListener touchListener = new SwipeDismissListViewTouchListener(listView, new SwipeDismissListViewTouchListener.OnDismissCallback() {
            @Override
            public void onDismiss(ListView listView, int[] reverseSortedPositions) {
                for (int position : reverseSortedPositions) {
                    Log.e("Hello", "Hello");
                    myListAdapter.remove(position);
                }
                myListAdapter.notifyDataSetChanged();
            }
        });
        listView.setOnTouchListener(touchListener);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /*
         * ListAdapter myListAdapter = new ArrayAdapter<String>( getActivity(), android.R.layout.simple_list_item_1, month); setListAdapter(myListAdapter);
         */
        myListAdapter = new MyListAdapter(getActivity(), R.layout.row, month);
        setListAdapter(myListAdapter);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.listfragment1, container, false);
    }

    @Override
    public void onListItemClick(ListView listView, View v, int position, long id) {
        // Toast.makeText(getActivity(), getListView().getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
        //
        // SwipeDismissListViewTouchListener touchListener = new SwipeDismissListViewTouchListener(listView, new SwipeDismissListViewTouchListener.OnDismissCallback() {
        // @Override
        // public void onDismiss(ListView listView, int[] reverseSortedPositions) {
        // for (int position : reverseSortedPositions) {
        // Log.e("Hello", "Hello");
        // myListAdapter.remove(position);
        // }
        // myListAdapter.notifyDataSetChanged();
        // }
        // });
        // listView.setOnTouchListener(touchListener);
    }

}

class MyGestureDetector extends SimpleOnGestureListener {

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        Log.e("There", "There");
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            // right to left swipe
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(fragmentActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(fragmentActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            // nothing
        }
        return false;
    }

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

这是 SwipeDismissListViewTouchListener。

// THIS IS A BETA! I DON'T RECOMMEND USING IT IN PRODUCTION CODE JUST YET

 /*
  * Copyright 2012 Roman Nurik
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */

 package com.example.android.swipedismiss;

 import android.graphics.Rect;
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
 import android.widget.ListView;
 import com.nineoldandroids.animation.Animator;
 import com.nineoldandroids.animation.AnimatorListenerAdapter;
 import com.nineoldandroids.animation.ValueAnimator;
 import com.pepperpk.eventi.ui.adapter.AttendeesListAdapter;
 import com.pepperpk.eventi.ui.fragment.AttendeesInnerFragment;
 import com.pepperpk.eventi.ui.fragment.AttendeesListFragment;

 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;

 import static com.nineoldandroids.view.ViewHelper.setAlpha;
 import static com.nineoldandroids.view.ViewHelper.setTranslationX;
 import static com.nineoldandroids.view.ViewPropertyAnimator.animate;


 public class SwipeDismissListViewTouchListener implements View.OnTouchListener {
// Cached ViewConfiguration and system-wide constant values
private int mSlop;
private int mMinFlingVelocity;
private int mMaxFlingVelocity;
private long mAnimationTime;

// Fixed properties
private ListView mListView;
private OnDismissCallback mCallback;
private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero

// Transient properties
private List<PendingDismissData> mPendingDismisses = new ArrayList<PendingDismissData>();
private int mDismissAnimationRefCount = 0;
private float mDownX;
private boolean mSwiping;
private VelocityTracker mVelocityTracker;
private int mDownPosition;
private View mDownView;
private boolean mPaused;
int selectedPosition;

/**
 * The callback interface used by {@link SwipeDismissListViewTouchListener} to inform its client about a successful dismissal of one or more list item positions.
 */
public interface OnDismissCallback {
    /**
     * Called when the user has indicated they she would like to dismiss one or more list item positions.
     * 
     * @param listView
     *            The originating {@link ListView}.
     * @param reverseSortedPositions
     *            An array of positions to dismiss, sorted in descending order for convenience.
     */
    void onDismiss(ListView listView, int[] reverseSortedPositions);
}

/**
 * Constructs a new swipe-to-dismiss touch listener for the given list view.
 * 
 * @param listView
 *            The list view whose items should be dismissable.
 * @param callback
 *            The callback to trigger when the user has indicated that she would like to dismiss one or more list items.
 */
public SwipeDismissListViewTouchListener(ListView listView, OnDismissCallback callback) {
    ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
    mSlop = vc.getScaledTouchSlop();
    mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
    mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
    mAnimationTime = listView.getContext().getResources().getInteger(android.R.integer.config_shortAnimTime);
    mListView = listView;
    mCallback = callback;
}

/**
 * Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures.
 * 
 * @param enabled
 *            Whether or not to watch for gestures.
 */
public void setEnabled(boolean enabled) {
    mPaused = !enabled;
}

/**
 * Returns an {@link android.widget.AbsListView.OnScrollListener} to be added to the {@link ListView} using {@link ListView#setOnScrollListener(android.widget.AbsListView.OnScrollListener)}. If a scroll listener is already assigned, the caller should still pass scroll changes through to this
 * listener. This will ensure that this {@link SwipeDismissListViewTouchListener} is paused during list view scrolling.</p>
 * 
 * @see {@link SwipeDismissListViewTouchListener}
 */
public AbsListView.OnScrollListener makeScrollListener() {
    return new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int scrollState) {
            setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
        }

        @Override
        public void onScroll(AbsListView absListView, int i, int i1, int i2) {
        }
    };
}

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    if (mViewWidth < 2) {
        mViewWidth = mListView.getWidth();
    }

    switch (motionEvent.getActionMasked()) {
    case MotionEvent.ACTION_DOWN: {
        if (mPaused) {
            return false;
        }

        // TODO: ensure this is a finger, and set a flag

        // Find the child view that was touched (perform a hit test)
        Rect rect = new Rect();
        int childCount = mListView.getChildCount();
        int[] listViewCoords = new int[2];
        mListView.getLocationOnScreen(listViewCoords);
        int x = (int) motionEvent.getRawX() - listViewCoords[0];
        int y = (int) motionEvent.getRawY() - listViewCoords[1];
        View child;
        for (int i = 0; i < childCount; i++) {
            child = mListView.getChildAt(i);
            child.getHitRect(rect);
            if (rect.contains(x, y)) {
                mDownView = child;
                break;
            }
        }

        if (mDownView != null) {
            mDownX = motionEvent.getRawX();
            mDownPosition = mListView.getPositionForView(mDownView);

            mVelocityTracker = VelocityTracker.obtain();
            mVelocityTracker.addMovement(motionEvent);
        }
        view.onTouchEvent(motionEvent);
        return true;
    }

    case MotionEvent.ACTION_UP: {
        if (mVelocityTracker == null) {
            break;
        }

        float deltaX = motionEvent.getRawX() - mDownX;
        mVelocityTracker.addMovement(motionEvent);
        mVelocityTracker.computeCurrentVelocity(1000);
        float velocityX = Math.abs(mVelocityTracker.getXVelocity());
        float velocityY = Math.abs(mVelocityTracker.getYVelocity());
        boolean dismiss = false;
        boolean dismissRight = false;
        if (Math.abs(deltaX) > mViewWidth / 2) {
            dismiss = true;
            dismissRight = deltaX > 0;
        } else if (mMinFlingVelocity <= velocityX && velocityX <= mMaxFlingVelocity && velocityY < velocityX) {
            dismiss = true;
            dismissRight = mVelocityTracker.getXVelocity() > 0;
        }
        if (dismiss) {
            if (dismissRight) {
                Log.e("Right", "Right");
            } else {
                Log.e("Left", "Left");
            }
            // dismiss
            final View downView = mDownView; // mDownView gets null'd before animation ends
            final int downPosition = mDownPosition;
            ++mDismissAnimationRefCount;
            animate(mDownView).translationX(dismissRight ? mViewWidth : -mViewWidth).alpha(0).setDuration(mAnimationTime).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    performDismiss(downView, downPosition);
                    Log.e("Here i am", "Here i am");
                }
            });
        } else {
            // cancel
            Log.e("Here i am else", "Here i am else");
            animate(mDownView).translationX(0).alpha(1).setDuration(mAnimationTime).setListener(null);
            ((AttendeesListAdapter)mListView.getAdapter()).onClick(selectedPosition);

        }
        mVelocityTracker = null;
        mDownX = 0;
        mDownView = null;
        mDownPosition = ListView.INVALID_POSITION;
        mSwiping = false;
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        if (mVelocityTracker == null || mPaused) {
            break;
        }

        mVelocityTracker.addMovement(motionEvent);
        float deltaX = motionEvent.getRawX() - mDownX;
        if (Math.abs(deltaX) > mSlop) {
            mSwiping = true;
            mListView.requestDisallowInterceptTouchEvent(true);

            // Cancel ListView's touch (un-highlighting the item)
            MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
            cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
            mListView.onTouchEvent(cancelEvent);
        }

        if (mSwiping) {
            setTranslationX(mDownView, deltaX);
            setAlpha(mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth)));
            return true;
        }
        break;
    }
    }
    return false;
}

class PendingDismissData implements Comparable<PendingDismissData> {
    public int position;
    public View view;

    public PendingDismissData(int position, View view) {
        this.position = position;
        this.view = view;
    }

    @Override
    public int compareTo(PendingDismissData other) {
        // Sort by descending position
        return other.position - position;
    }
}

private void performDismiss(final View dismissView, final int dismissPosition) {
    // Animate the dismissed list item to zero-height and fire the dismiss callback when
    // all dismissed list item animations have completed. This triggers layout on each animation
    // frame; in the future we may want to do something smarter and more performant.

    final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
    final int originalHeight = dismissView.getHeight();

    ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);

    animator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            --mDismissAnimationRefCount;
            if (mDismissAnimationRefCount == 0) {
                // No active animations, process all pending dismisses.
                // Sort by descending position
                Collections.sort(mPendingDismisses);

                int[] dismissPositions = new int[mPendingDismisses.size()];
                for (int i = mPendingDismisses.size() - 1; i >= 0; i--) {
                    dismissPositions[i] = mPendingDismisses.get(i).position;
                }
                mCallback.onDismiss(mListView, dismissPositions);

                ViewGroup.LayoutParams lp;
                for (PendingDismissData pendingDismiss : mPendingDismisses) {
                    // Reset view presentation
                    setAlpha(pendingDismiss.view, 1f);
                    setTranslationX(pendingDismiss.view, 0);
                    lp = pendingDismiss.view.getLayoutParams();
                    lp.height = originalHeight;
                    pendingDismiss.view.setLayoutParams(lp);
                }

                mPendingDismisses.clear();
            }
        }
    });

    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            lp.height = (Integer) valueAnimator.getAnimatedValue();
            dismissView.setLayoutParams(lp);
        }
    });

    mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));
    // animator.start();

    --mDismissAnimationRefCount;
    if (mDismissAnimationRefCount == 0) {
        // No active animations, process all pending dismisses.
        // Sort by descending position
        Collections.sort(mPendingDismisses);

        int[] dismissPositions = new int[mPendingDismisses.size()];
        for (int i = mPendingDismisses.size() - 1; i >= 0; i--) {
            dismissPositions[i] = mPendingDismisses.get(i).position;
        }
        mCallback.onDismiss(mListView, dismissPositions);

        ViewGroup.LayoutParams lpp;
        for (PendingDismissData pendingDismiss : mPendingDismisses) {
            // Reset view presentation
            setAlpha(pendingDismiss.view, 1f);
            setTranslationX(pendingDismiss.view, 0);
            lpp = pendingDismiss.view.getLayoutParams();
            lpp.height = originalHeight;
            pendingDismiss.view.setLayoutParams(lp);
        }

        mPendingDismisses.clear();
    }
}
 }
于 2014-04-17T05:16:07.253 回答