在Android自定义列表视图中滑动右侧显示按钮

时间:2013-04-25 15:36:32

标签: android listview android-listview adapter onfling

我正在尝试实施,在自定义列表视图中向右滑动显示按钮。我现在面临的问题是,我实现了我在网上找到的onSwipeTouchListener。我能够看到滑动按钮。但它不一致,我的意思是如果我向右滑动一行,按钮显示在另一行。这是我试过的。

我创建了一个用于保存视图的适配器

//TransactionAddDropViewHolder


        public static final class TransactionAddDropViewHolder {

    public View moveUpButton = null;
    public View moveDownButton = null;
    public View withdrawButton = null;
    public View reviewButton = null;

    public View approveButton = null;
    public View rejectButton = null;

    public LinearLayout addContainer = null;
    public LinearLayout dropContainer = null;



    public void swipeButtons() {
        addDropListView.setOnTouchListener(new OnSwipeTouchListener() {

            public void onSwipeRight() {
                withdrawButton.setVisibility(View.VISIBLE);
            }

            public void onSwipeLeft() {
                withdrawButton.setVisibility(View.INVISIBLE);
            }
        });
    }

    public void showUserButtons() {
        this.moveUpButton.setVisibility(View.VISIBLE);
        this.moveDownButton.setVisibility(View.VISIBLE);
        // this.withdrawButton.setVisibility(View.VISIBLE);
    }

    public void hideUserButtons() {
        this.moveUpButton.setVisibility(View.GONE);
        this.moveDownButton.setVisibility(View.GONE);
        // this.withdrawButton.setVisibility(View.GONE);
    } 

}

这是我的自定义视图,我在其中显示onSwipeButton

@Override
    public View getView(final int position, View convertView,
            ViewGroup parent) {

        final TransactionAddDrop addDropData = this.addDropList.get(position);

        TransactionAddDropViewHolder holder = null;

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.fragment_pending_transaction_list_item, null);
            holder = new TransactionAddDropViewHolder();

holder.withdrawButton = convertView.findViewById(R.id.pendingTransactionItem_withdrawButton);
            holder.addContainer = (LinearLayout) convertView.findViewById(R.id.pendingTransactionItem_addContainer);
            **holder.swipeButtons();** 
            convertView.setTag(holder);
        } else {
            holder = (TransactionAddDropViewHolder) convertView.getTag();
            holder.swipeButtons(); 
        }

这是我的OnSwipeTouchListener类

    private final class GestureListener extends SimpleOnGestureListener {

    private static final int SWIPE_THRESHOLD = 100;
    private static final int SWIPE_VELOCITY_THRESHOLD = 100;

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

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        boolean result = false;
        try {
            float diffY = e2.getY() - e1.getY();
            float diffX = e2.getX() - e1.getX();
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        onSwipeRight();
                    } else {
                        onSwipeLeft();
                    }
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom();
                    } else {
                        onSwipeTop();
                    }
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}

添加XML布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.cbssports.nflapp.ffb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/swipeRight"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/claimlayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <LinearLayout
        android:id="@+id/claim"
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="10dp" >

        <com.cbssports.nflapp.ffb.CustomText
            android:id="@+id/claimNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="1"
            android:textColor="#B4B4B5"
            android:textSize="36dp"
            app:typeface="oswald_regular" />
    </LinearLayout>

    <RelativeLayout
        android:id="@+id/pendingPlayers"
        android:layout_width="200dp"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:id="@+id/tradeDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:orientation="horizontal"
            android:layout_toRightOf="@+id/claimlayout"
            android:paddingTop="5dp" >

            <com.cbssports.nflapp.ffb.CustomText
                android:id="@+id/pendingTransactionItem_teamName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#B4B4B5"
                android:textSize="9dp"
                app:typeface="oswald_regular" />

            <com.cbssports.nflapp.ffb.CustomText
                android:id="@+id/pendingTransactionItem_bidAmount"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#797979"
                android:text=""
                android:textColor="#ffffff"
                android:textSize="9dp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/adddropView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tradeDate"
            android:layout_toRightOf="@+id/claimlayout"
            android:orientation="vertical" >

            <LinearLayout
                android:id="@+id/addViewContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <com.cbssports.nflapp.ffb.CustomText
                    android:layout_width="50dp"
                    android:layout_height="wrap_content"
                    android:paddingRight="10dp"
                    android:text="ADD"
                    android:textColor="#797979"
                    android:textSize="15dp"
                    app:typeface="oswald_regular" />

                <LinearLayout
                    android:id="@+id/pendingTransactionItem_addContainer"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" />
            </LinearLayout>

            <LinearLayout
                android:id="@+id/adddropViewContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/claimlayout"
                android:orientation="horizontal" >

                <com.cbssports.nflapp.ffb.CustomText
                    android:layout_width="50dp"
                    android:layout_height="wrap_content"
                    android:paddingRight="10dp"
                    android:text="DROP"
                    android:textColor="#797979"
                    android:textSize="15dp"
                    app:typeface="oswald_regular" />

                <LinearLayout
                    android:id="@+id/pendingTransactionItem_dropContainer"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" />
            </LinearLayout>
        </LinearLayout>
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/pendingTransactionItem_userButtonContainer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_gravity="center_vertical"
        android:layout_toRightOf="@+id/pendingPlayers"
        android:gravity="center"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_gravity="center_vertical"
            android:gravity="center"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/pendingTransactionItem_moveUpButton"
                android:layout_width="20dp"
                android:layout_height="15dp"
                android:layout_margin="3dp"
                android:background="@drawable/gfx_up_arrow"
                android:padding="1dp"
                android:textColor="#ffffff"
                android:textSize="7sp"
                android:visibility="visible" />

            <Button
                android:id="@+id/pendingTransactionItem_moveDownButton"
                android:layout_width="20dp"
                android:layout_height="15dp"
                android:layout_margin="3dp"
                android:background="@drawable/gfx_down_arrow"
                android:padding="1dp"
                android:textColor="#ffffff"
                android:textSize="7sp"
                android:visibility="visible" />
        </LinearLayout>

        <ImageView
            android:id="@+id/pendingTransactionItem_withdrawButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="1dp"
            android:src="@drawable/ic_cancelclaim"
            android:visibility="gone" />

        <!-- Transaction Review -->

        <ImageView
            android:id="@+id/pendingTransactionItem_reviewButton"
            android:layout_width="38dp"
            android:layout_height="38dp"
            android:padding="1dp"
            android:src="@drawable/btn_review"
            android:visibility="gone" />
    </LinearLayout>
</LinearLayout>

再添一个问题。得到视图的总计数。但是想要在不同的布局中显示。这是我的onCreatedView

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    fragmentPendingTrades = inflater.inflate(R.layout.fragment_transactions_pending, container, false);
    pendingTradesView = inflater;

    return fragmentPendingTrades;
}

    public void onViewCreated(final View view, final Bundle savedInstanceState) {

    this.addDropListView = (ListView) view.findViewById(R.id.transactions_pending_transactionsListView);
    this.addDropAdapter = new TransactionAddDropAdapter(pendingTradesView);
    this.addDropListView.setAdapter(this.addDropAdapter);
    this.emptyTransationsContainer = view.findViewById(R.id.transactions_pending_transactions_emptyContainer);



    TextView getTotalCount = (TextView) view.findViewById(R.id.transactions_pending_TransactionsAddDropCount);

    getTotalCount.setText(""+addDropListView.getCount());



}

1 个答案:

答案 0 :(得分:1)

所以,我可以通过两种方式完成这项工作:

  1. 听取整个列表中的滑动,找出刷过的行,并显示/隐藏正确行的按钮。
  2. 听取每行的滑动,并显示/隐藏该行的按钮。
  3. 现在您正在列表中设置侦听器,但尝试应用显示/隐藏适配器中附加的按钮。在某种程度上,您正在执行每个解决方案的一半。有了你所拥有的,我建议你选择#2。

    TransactionAddDropViewHolder中,您需要在行布局中获得对根View的引用,因此我们可以将OnSwipeTouchListener设置为它。

    public static final class TransactionAddDropViewHolder {
    
        public View rootView = null;
    
        // Your other code
    
        public void swipeButtons() {
            rootView.setOnTouchListener(new OnSwipeTouchListener() {
    
                public void onSwipeRight() {
                    withdrawButton.setVisibility(View.VISIBLE);
                }
    
                public void onSwipeLeft() {
                    withdrawButton.setVisibility(View.INVISIBLE);
                }
            });
        }
    
        // Your other code
    
    }
    

    接下来,在您的getView方法中,对其进行更新,以便TransactionAddDropViewHolder获得对布局中根View的引用。

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
    
        final TransactionAddDrop addDropData = this.addDropList.get(position);
    
        TransactionAddDropViewHolder holder = null;
    
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.fragment_pending_transaction_list_item, null);
            holder = new TransactionAddDropViewHolder();
    
            // Get a reference to the root of the row layout
            holder.rootView = convertView.findViewById(R.id.swipeRight); 
    
            holder.withdrawButton = convertView.findViewById(R.id.pendingTransactionItem_withdrawButton);
            holder.addContainer = (LinearLayout) convertView.findViewById(R.id.pendingTransactionItem_addContainer);
    
            holder.swipeButtons();
            convertView.setTag(holder);
        } else {
            holder = (TransactionAddDropViewHolder) convertView.getTag();
            holder.swipeButtons(); 
        }
    }
    

    还有一个问题,刷卡时按钮会正确显示,但如果用户继续滚动,它将出现在其他行上。这是因为ListView回收了它的行View。我建议你做两件事:

    1. 当用户在按钮出现后再次开始滚动时,会再次隐藏它。这就是iOS在列表中“滑动删除”的功能。
    2. 如果行处于可见按钮的模式,例如boolean,请使用isDeleteShowing存储在数据对象中。然后在onSwipe回调中,将isDeleteShowing设置为true / false。最后,在getView中,您可以根据该数据行的isDeleteShowing显示/隐藏按钮。
    3. 希望这一切都有所帮助。