由于某些原因,在listView项目上滑动时未检测到滑动。我发现这个功能在正常活动中有效,但是当在片段或对话框片段中时,"轻扫以删除"功能不起作用,我需要在一个片段中,所以我想看看是否有人知道如果可能的话如何让这个在片段中工作。我从https://github.com/JohannBlake/ListViewOrderAndSwipe
获得了代码这是我的代码中的实现: 我在对话框片段中有listView UserFavoritesDialogFragment.java
public class UserFavoritesDialogFragment extends DialogFragment {
private final String TAG_LOG = "User Favorites";
private final String TAG_BOTTOM_VIEW = "BottomView";
private ArrayList<Person> mPersons = new ArrayList<>();
private PersonAdapter mAdapterPerson;
private PersonListViewOrder mPersonsListView;
private ViewGroup mSwipedViewGroup;
private JBHorizontalSwipe mJBHorizontalSwipe;
private boolean mRemovePrevDeleted;
private Person mPrevDeletedPerson;
Context mContext;
static UserFavoritesDialogFragment newInstance(Context context) {
Context mContext = context;
UserFavoritesDialogFragment f = new UserFavoritesDialogFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View vdialog = inflater.inflate(R.layout.user_favorites, container, false);
getDialog().setTitle("User Favorites");
Log.d("User Favorites Dialog: ", "Horizontal Swipe before: " + mJBHorizontalSwipe);
// The main activity needs a HorizontalSwipe object to handle swiping listview items.
mJBHorizontalSwipe = new JBHorizontalSwipe(ijbHorizontalSwipe);
Log.d("User Favorites Dialog: ", "Horizontal Swipe after: " + mJBHorizontalSwipe);
// Add some data to the listview.
mPersons.add(new Person(getNewId(), "Ben", BitmapFactory.decodeResource(getResources(), R.drawable.ic_ben)));
mPersons.add(new Person(getNewId(), "Brad", BitmapFactory.decodeResource(getResources(), R.drawable.ic_brad)));
mPersons.add(new Person(getNewId(), "Bradley", BitmapFactory.decodeResource(getResources(), R.drawable.ic_bradley)));
mPersons.add(new Person(getNewId(), "Bruce", BitmapFactory.decodeResource(getResources(), R.drawable.ic_bruce)));
mPersons.add(new Person(getNewId(), "Chris", BitmapFactory.decodeResource(getResources(), R.drawable.ic_chris)));
mPersons.add(new Person(getNewId(), "Christian", BitmapFactory.decodeResource(getResources(), R.drawable.ic_christian)));
mPersons.add(new Person(getNewId(), "Denzel", BitmapFactory.decodeResource(getResources(), R.drawable.ic_denzel)));
mPersons.add(new Person(getNewId(), "George", BitmapFactory.decodeResource(getResources(), R.drawable.ic_george)));
mPersons.add(new Person(getNewId(), "Hugh", BitmapFactory.decodeResource(getResources(), R.drawable.ic_hugh)));
mPersons.add(new Person(getNewId(), "Johnny", BitmapFactory.decodeResource(getResources(), R.drawable.ic_johnny)));
mPersons.add(new Person(getNewId(), "Leo", BitmapFactory.decodeResource(getResources(), R.drawable.ic_leo)));
mPersons.add(new Person(getNewId(), "Liam", BitmapFactory.decodeResource(getResources(), R.drawable.ic_liam)));
mPersons.add(new Person(getNewId(), "Matt", BitmapFactory.decodeResource(getResources(), R.drawable.ic_matt)));
mPersons.add(new Person(getNewId(), "Matthew", BitmapFactory.decodeResource(getResources(), R.drawable.ic_matthew)));
mPersons.add(new Person(getNewId(), "Morgan", BitmapFactory.decodeResource(getResources(), R.drawable.ic_morgan)));
mPersons.add(new Person(getNewId(), "Russell", BitmapFactory.decodeResource(getResources(), R.drawable.ic_russell)));
mPersons.add(new Person(getNewId(), "Tom", BitmapFactory.decodeResource(getResources(), R.drawable.ic_tom)));
mPersons.add(new Person(getNewId(), "Will", BitmapFactory.decodeResource(getResources(), R.drawable.ic_will)));
Log.d("User Favorites Dialog: ", "Person Array: " + mPersons);
mPersonsListView = (PersonListViewOrder) vdialog.findViewById(R.id.lvPersons);
mPersonsListView.setPersonList(mPersons);
mAdapterPerson = new PersonAdapter(getActivity(), R.layout.person_item, mPersons, mJBHorizontalSwipe, mPersonsListView, new IListItemControls() {
@Override
public void onUndoClicked(View v) {
// When the Undo button on a list item is pressed, we need to reset the state of deletion.
mRemovePrevDeleted = false;
mPrevDeletedPerson = null;
}
});
mPersonsListView.setAdapter(mAdapterPerson);
mPersonsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// This is where you put your code to handle the user tapping on a list item, i.e.
// when the item's top view is being displayed.
Person person = (Person) view.getTag();
Toast.makeText(getActivity(), person.name, Toast.LENGTH_SHORT).show();
}
});
// Handles removing a deleted item if the user scrolls the listview.
// NOTE: Don't use a ScrollListener on the listview as this will cause bad
// side effects. Motion events for the listview must be handled by the
// onTouchEvent method in PersonListViewOrder in order for this kind of listview
// to function properly.
mPersonsListView.setVerticalScrollCallback(new PersonListViewOrder.IVerticalScrollCallback() {
@Override
public void onVerticalScroll() {
// This method gets called when the user scrolls the listview vertically.
if (mPrevDeletedPerson != null) {
int pos = mAdapterPerson.getPosition(mPrevDeletedPerson);
View vPrevDeleted = mPersonsListView.getChildAt(pos - mPersonsListView.getFirstVisiblePosition());
mAdapterPerson.animateRemoval(vPrevDeleted);
mRemovePrevDeleted = false;
mPrevDeletedPerson = null;
}
}
});
return vdialog;
}
/**
* Used to handle callbacks when the user swipes list items.
*/
private JBHorizontalSwipe.IJBHorizontalSwipe ijbHorizontalSwipe = new JBHorizontalSwipe.IJBHorizontalSwipe() {
@Override
public void onReposition(float x, boolean scrollingRight, float scrollDelta) {
// Currently not used. You can use this callback to do something while the user is swiping a list item.
}
@Override
public void onTopViewVisibilityChange(View vTop, boolean visible) {
// This callback gets called when the list item's top view changes from fully visible to
// fully invisible.
mSwipedViewGroup = (ViewGroup) vTop.getParent();
final Person person = (Person) mSwipedViewGroup.getTag();
person.deleted = !visible;
mRemovePrevDeleted = false;
// Using setPressed is necessary in various places throughout the app in order
// to restore the background color of the top view. This is required because list
// items don't receive the ACTION_UP event which would normally restore the background
// color. The ACTION_UP is not received because code in PersonListViewOrder as well
// JBHorizontalSwipe and CustomListItem intercept the motion events and take over
// control when a ACTION_DOWN is received.
vTop.setPressed(false);
mPersonsListView.setPressed(false);
if ((person == mPrevDeletedPerson) && !person.deleted)
mPrevDeletedPerson = null;
if ((person.deleted) && (mPrevDeletedPerson != null) && (person != mPrevDeletedPerson))
mRemovePrevDeleted = true;
View vBottom = mSwipedViewGroup.findViewWithTag(TAG_BOTTOM_VIEW);
PropertyValuesHolder pvhAlphaCurrent;
ButtonBottomView btnUndo = (ButtonBottomView) vBottom.findViewById(R.id.btnUndo);
mAdapterPerson.onItemSwiped(person, btnUndo);
// If the top view is swiped out of view, we want to animate the bottom view's
// visibility to gradually show, which is done by changing its alpha.
if (person.deleted)
pvhAlphaCurrent = PropertyValuesHolder.ofFloat("alpha", 0, 1);
else
pvhAlphaCurrent = PropertyValuesHolder.ofFloat("alpha", 1, 0);
ObjectAnimator animatorView = ObjectAnimator.ofPropertyValuesHolder(vBottom, pvhAlphaCurrent);
animatorView.setInterpolator(new LinearInterpolator());
animatorView.setDuration(300);
animatorView.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
// If a previous item has been deleted but is still visible, we
// need to remove it from the list using some animation.
if (mRemovePrevDeleted) {
int pos = mAdapterPerson.getPosition(mPrevDeletedPerson);
if ((pos >= mPersonsListView.getFirstVisiblePosition()) && (pos <= mPersonsListView.getLastVisiblePosition())) {
View vPrevDeleted = mPersonsListView.getChildAt(pos - mPersonsListView.getFirstVisiblePosition());
mAdapterPerson.animateRemoval(vPrevDeleted);
} else {
mAdapterPerson.remove(mPrevDeletedPerson);
}
}
if (person.deleted)
mPrevDeletedPerson = person;
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorView.start();
}
};
/**
* Used to intercept touch events. THIS LOOKS LIKE IT NEEDS TO BE CALLED TO HANDLE THE SWIPE BUT ITS NEVER CALLED. WHY IS THIS?
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("User Favorites Dialog: ", "Touch event dispatch called ");
if (mJBHorizontalSwipe != null)
mJBHorizontalSwipe.onRootDispatchTouchEventListener(ev);
return super.getActivity().dispatchTouchEvent(ev);
}
/**
* Generates a unique ID.
*
* @return Returns a random number.
*/
private long getNewId() {
Random r = new Random();
return r.nextLong();
}
interface IListItemControls {
/**
* A callback that gets called when the user taps on the Undo button.
*
* @param v The view that represents the Undo button.
*/
void onUndoClicked(View v);
}
}
JBHorizontalSwipe.java
public class JBHorizontalSwipe {
private final String LOG_TAG = "JBHorizontalSwipe";
private final String TAG_TOP_VIEW = "TopView";
private boolean mFingerUp;
private float mScrollDeltaX;
private float mScrollDeltaY;
private float mMotionEventPrevX;
private float mMotionEventPrevY;
private boolean mScrollingRight;
private View mScrollerView;
private IJBHorizontalSwipe mIJBHorizontalSwipe;
private ObjectAnimator mAnimatorView;
private boolean mAnimating;
private boolean mCancelAnimation;
private float mInitialLeft;
private boolean mTopViewChanged;
private boolean mTopViewVisible;
public final static int ANIMATE_POSITION_LEFT_VISIBLE = 0;
public final static int ANIMATE_POSITION_LEFT_INVISIBLE = 1;
public final static int ANIMATE_POSITION_RIGHT_VISIBLE = 2;
public final static int ANIMATE_POSITION_RIGHT_INVISIBLE = 3;
public JBHorizontalSwipe(IJBHorizontalSwipe ijbHorizontalSwipe) {
mIJBHorizontalSwipe = ijbHorizontalSwipe;
}
/**
* Receives motion events from the scroller. Scrollers must implement the dispatchTouchEvent method and call this
* method from there.
*
* @param v Indicates the scroller that sent the motion event.
* @param event The motion event that was sent.
*/
public void onScrollerDispatchTouchEventListener(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d("User Favorites Dialog: ", "Touch event connected ");
mScrollerView = v;
View vTop = mScrollerView.findViewWithTag(TAG_TOP_VIEW);
mInitialLeft = vTop.getX();
}else{
Log.d("User Favorites Dialog: ", "Touch event disconnected ");
}
}
public void onRootDispatchTouchEventListener(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
// Reposition the top view if necessary.
mFingerUp = true;
if (mScrollerView != null) {
View vTop = mScrollerView.findViewWithTag(TAG_TOP_VIEW);
if ((vTop != null) && (vTop.getX() != 0))
processViewPosition(vTop);
mScrollerView = null;
}
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
mFingerUp = false;
mMotionEventPrevX = event.getX();
mMotionEventPrevY = event.getY();
}
if ((event.getAction() == MotionEvent.ACTION_MOVE) && (mScrollerView != null)) {
// Adjust the position of the view.
mScrollingRight = event.getX() > mMotionEventPrevX;
mScrollDeltaX = Math.abs(event.getX() - mMotionEventPrevX);
mScrollDeltaY = Math.abs(event.getY() - mMotionEventPrevY);
mMotionEventPrevX = event.getX();
mMotionEventPrevY = event.getY();
View vTop = mScrollerView.findViewWithTag(TAG_TOP_VIEW);
if (((mScrollDeltaX > 10) && (mScrollDeltaY < 10)) || ((vTop != null) && (vTop.getX() != 0))) {
IJBHorizontalSwipeTouch ijbHorizontalSwipeTouch = (IJBHorizontalSwipeTouch) mScrollerView.getParent();
ijbHorizontalSwipeTouch.setDisableScrolling(true);
ListView listview = (ListView) vTop.getParent().getParent();
listview.requestDisallowInterceptTouchEvent(true);
repositionTopView();
}
}
}
/**
* Repositions the top view when the user scrolls it horizontally.
*/
private void repositionTopView() {
View vTop = mScrollerView.findViewWithTag(TAG_TOP_VIEW);
if (mAnimating || mFingerUp)
return;
if (mScrollingRight) {
float x = vTop.getX() + mScrollDeltaX;
if (vTop.getX() >= (vTop.getWidth() - 1))
vTop.setX(-(vTop.getWidth() - 1));
else
vTop.setX(x);
} else {
float x = vTop.getX() - mScrollDeltaX;
if (vTop.getX() <= -(vTop.getWidth() - 1))
vTop.setX(vTop.getWidth());
else
vTop.setX(x);
}
// Change the alpha of the top view as it is being scrolled making it dimmer as it moves off the screen.
float alpha = (vTop.getWidth() - Math.abs(vTop.getX() - mScrollDeltaX)) / vTop.getWidth();
vTop.setAlpha(alpha);
}
/**
* This is where the decision is made to either display or hide the view.
*/
private void processViewPosition(View vTop) {
if (mFingerUp) {
if (mScrollerView == null)
return;
if (mScrollingRight && (mScrollDeltaX > 50) && (vTop.getX() > 0)) {
animateView(vTop, ANIMATE_POSITION_RIGHT_INVISIBLE);
return;
}
if (mScrollingRight && (mScrollDeltaX > 50) && (vTop.getX() < 0)) {
animateView(vTop, ANIMATE_POSITION_RIGHT_VISIBLE);
return;
}
if (!mScrollingRight && (mScrollDeltaX > 50) && (vTop.getX() > 0)) {
animateView(vTop, ANIMATE_POSITION_LEFT_VISIBLE);
return;
}
if (!mScrollingRight && (mScrollDeltaX > 50) && (vTop.getX() < 0)) {
animateView(vTop, ANIMATE_POSITION_LEFT_INVISIBLE);
return;
}
// View was moved to the right of its origin.
if ((mInitialLeft == 0) && (vTop.getX() > 0) && (vTop.getX() < mScrollerView.getWidth() / 3)) {
animateView(vTop, ANIMATE_POSITION_LEFT_VISIBLE);
return;
} else if ((mInitialLeft == 0) && (vTop.getX() >= mScrollerView.getWidth() / 3)) {
animateView(vTop, ANIMATE_POSITION_RIGHT_INVISIBLE);
return;
} else if ((mInitialLeft == 0) && (vTop.getX() > -mScrollerView.getWidth() / 3)) {
animateView(vTop, ANIMATE_POSITION_RIGHT_VISIBLE);
return;
} else if (mInitialLeft == 0) {
animateView(vTop, ANIMATE_POSITION_LEFT_INVISIBLE);
return;
} else if ((mInitialLeft > 0) && (vTop.getX() >= mScrollerView.getWidth() * 2 / 3)) {
animateView(vTop, ANIMATE_POSITION_RIGHT_INVISIBLE);
return;
} else if (mInitialLeft > 0) {
animateView(vTop, ANIMATE_POSITION_LEFT_VISIBLE);
return;
} else if ((mInitialLeft < 0) && (vTop.getX() > -mScrollerView.getWidth() * 2 / 3)) {
animateView(vTop, ANIMATE_POSITION_RIGHT_VISIBLE);
return;
} else {
animateView(vTop, ANIMATE_POSITION_LEFT_INVISIBLE);
return;
}
} else {
if (mAnimatorView != null)
mAnimatorView.cancel();
}
}
/**
* Makes the top view visible by animating it onto the screen from either
* the left or right side of the container depending on where its current
* left position is located.
*
* @param vTop The top view to make visible.
*/
public void showTopView(View vTop) {
if (vTop.getX() < 0)
animateView(vTop, ANIMATE_POSITION_RIGHT_VISIBLE);
else
animateView(vTop, ANIMATE_POSITION_LEFT_VISIBLE);
mTopViewVisible = true;
mTopViewChanged = true;
}
/**
* Shows or hides the top view by animating on to or off of the screen.
*
* @param vTop The top view.
* @param position Use ANIMATE_POSITION_LEFT_INVISIBLE to slide it off the screen in the left
* direction. Use ANIMATE_POSITION_RIGHT_INVISIBLE to slide it off the screen
* in the right direction. Set it to ANIMATE_POSITION_LEFT_VISIBLE or
* ANIMATE_POSITION_RIGHT_VISIBLE to slide it on to the screen.
*/
public void animateView(View vTop, int position) {
if (mAnimatorView != null)
mAnimatorView.cancel();
float left;
switch (position) {
case ANIMATE_POSITION_LEFT_INVISIBLE:
left = -vTop.getWidth();
break;
case ANIMATE_POSITION_RIGHT_INVISIBLE:
left = vTop.getWidth();
break;
default:
left = 0;
break;
}
mAnimating = true;
PropertyValuesHolder pvhXBar = PropertyValuesHolder.ofFloat("x", vTop.getX(), left);
mAnimatorView = ObjectAnimator.ofPropertyValuesHolder(vTop, pvhXBar);
mAnimatorView.setInterpolator(new LinearInterpolator());
mAnimatorView.setDuration(200);
mAnimatorView.addListener(animListener);
mCancelAnimation = false;
mAnimatorView.start();
if ((mIJBHorizontalSwipe != null) && (left != mInitialLeft)) {
mTopViewChanged = true;
mTopViewVisible = (position == ANIMATE_POSITION_LEFT_VISIBLE) || (position == ANIMATE_POSITION_RIGHT_VISIBLE);
} else
mTopViewChanged = false;
}
/**
* The animation listener. Needed to know when the animation should be canceled.
*/
private Animator.AnimatorListener animListener = new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (mCancelAnimation)
mAnimatorView.cancel();
}
@Override
public void onAnimationEnd(Animator animation) {
mAnimating = false;
mCancelAnimation = false;
View v = (View) mAnimatorView.getTarget();
v.setAlpha(1);
if ((mIJBHorizontalSwipe != null) && mTopViewChanged)
mIJBHorizontalSwipe.onTopViewVisibilityChange(v, mTopViewVisible);
}
@Override
public void onAnimationCancel(Animator animation) {
mCancelAnimation = false;
}
@Override
public void onAnimationRepeat(Animator animation) {
}
};
public interface IJBHorizontalSwipe {
void onReposition(float x, boolean scrollingRight, float scrollDelta);
void onTopViewVisibilityChange(View vTop, boolean visible);
}
public interface IJBHorizontalSwipeTouch {
void setDisableScrolling(boolean disable);
}
public interface IJBHorizontalSwipeAdapter {
View getSelectedView();
}
}
user_favorites.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:id="@+id/img">
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:rowCount="10"
android:columnCount="2"
android:padding="10dp"
android:elevation="1dp"
android:background="#313131">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="People"
android:layout_marginTop="10dp"
android:layout_column="0"
android:layout_row="0"
android:id="@+id/textViewPeople2" />
<View
android:id="@+id/HorizontalLine1"
android:layout_width="match_parent"
android:layout_column="0"
android:layout_columnSpan="2"
android:layout_row="1"
android:layout_height="1dip"
android:background="#aaa"
android:layout_marginTop="10dp" />
<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"
android:layout_column="0"
android:layout_columnSpan="2"
android:layout_row="2"
tools:context=".UserFavoritesDialogFragment">
<view
android:id="@+id/ListViewBackground"
class="com.example.rapid.rapid.ListViewItemBackground"
android:layout_width="match_parent"
android:layout_height="150dp">
<com.example.rapid.rapid.PersonListViewOrder
android:id="@+id/lvPersons"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#c0c0c0"
android:dividerHeight="1dp"
android:scrollingCache="true"/>
</view>
</RelativeLayout>
</GridLayout>
</ScrollView>
答案 0 :(得分:0)
快速查看表明您可能需要在user_favourite.xml文件的ScrollView中添加android:clickable="true"
。可能发生的事情是您的点击或触摸是否泄漏?通过而不被捕获。