簡體   English   中英

在Android中,如何在顧及由彈跳引起的加速的同時實現對列表視圖的捕捉效果?

[英]In Android, how to achieve snap effect on a listview while respecting acceleration caused by fling?

為了演示,我有一個ListView顯示一個數字列表。 我想達到這樣的效果:當用戶滾動ListView並結束滾動時,它只會停止在某些位置,這樣第一個可見項始終會完整顯示。 我在下面附加了我的嘗試代碼。 當用戶拖動以滾動ListView時,它可以工作。 但是,在猛沖時,正常的加速度會中斷,從而導致不自然的停止。 我的問題是,在達到相同效果的同時,如何考慮由猛擊引起的加速度?

package com.example.snaptest;

import android.content.Context;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {

    private static class TestListViewAdapter extends BaseAdapter {

        private Context mContext;

        public TestListViewAdapter(Context context) {
            mContext = context;
        }

        @Override
        public int getCount() {
            return 100;
        }

        @Override
        public Object getItem(int position) {
            return Integer.toString(position);
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textView = new TextView(mContext);
            textView.setText(Integer.toString(position));
            AbsListView.LayoutParams params = new AbsListView.LayoutParams(ViewGroup.LayoutParams
                    .MATCH_PARENT, 180);
            textView.setLayoutParams(params);
            return textView;
        }
    }

    private static class TestListView extends ListView {

        public TestListView(Context context) {
            super(context);
        }

        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
                View itemView = getChildAt(0);
                int top = Math.abs(itemView.getTop()); // top is a negative value
                int bottom = Math.abs(itemView.getBottom());
                if (top >= bottom){
                    smoothScrollToPositionFromTop
                            (getFirstVisiblePosition() + 1, 0);
                } else {
                    smoothScrollToPositionFromTop
                            (getFirstVisiblePosition(), 0);
                }
            }
            return super.onTouchEvent(ev);
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TestListView listView = new TestListView(this);
        listView.setAdapter(new TestListViewAdapter(this));
        setContentView(listView);
    }

}

我會嘗試使用OnScrollListener而不是擴展ListView

像這樣:

listView.setOnScrollListener(new AbsListView.OnScrollListener() {
  @Override
  public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (scrollState == AbsListView.SCROLL_STATE_IDLE) {
      // snap the listview according to the top/bottom items' visibility
    }
  }

  @Override
  public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM