0

ListViewを垂直ギャラリーのように表示する次のコードがあります

public class VerticalGallery extends ListView {
    private View currentDisplayingView;
    private int currentPosition;

    public VerticalGallery(Context context, List<Page> pages) {
            super(context);

        setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                currentDisplayingView = view;
                currentPosition = position;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        setAdapter(new PageAdapter(context, pages));

        setCacheColorHint(Color.TRANSPARENT);
    }

    public boolean onTouchEvent(MotionEvent evt) {
        if (currentDisplayingView != null && currentDisplayingView.onTouchEvent(evt))
            return true;

        PageAdapter adapter = (PageAdapter) getAdapter();

        if (currentPosition == adapter.list.size() - 1)
            return false;

        // TODO: Handle events and swipe somewhere
        return super.onTouchEvent(evt);
    }

    public class PageAdapter extends BaseAdapter {
        private Context context;
        private List<Page> list;

        public PageAdapter(Context c, List<Page> pages) {
            context = c;
            list = pages;
        }

        public int getCount() {
            return list.size();
        }

        public Page getItem(int position) {
            return list.get(position);
        }

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

        public View getView(int position, View convertView, ViewGroup parent) {
            View view = getItem(position).generateView(context);
            view.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.MATCH_PARENT));
            return view;
        }
    }    
}

ただし、シミュレートする必要のある動作もいくつかあります。

  • ビューを一元化する:新しいビューが表示されたら、ディスプレイ上で一元化する必要があります。
  • onItemSelectedイベントの発生:現在のビューにイベントをディスパッチし、touchEventでcurrentViewがfalseを返した場合にのみスクロールさせる原因が必要です。ItemSelectedListViewイベントは必要ありません。これは似たようなものです。
  • また、もう1つの質問は、ユーザーが上にスワイプした場合、1つのビューのみを翻訳する必要があることです(ジェスチャの速度に応じて複数のビューを翻訳する必要はありません)。

それを可能にするコンポーネントは、有用な答えにもなります。

編集:実際、私はこのソリューションでこの問題を解決しました。アニメーションを使用してビューをスワイプしますが、この質問は開いたままにしておきます。

4

2 に答える 2

0

同じリストビューでontouchとonflingの両方を実装する方法は?

GestureListenerクラスの実装に関するこの質問の受け入れられた回答を読んでください。

MyGestureListenerクラスを現在のクラスの内部として作成するか、ListViewオブジェクトをMyGestureListenerクラスのコンストラクターに渡します。

onFling()メソッドで、次のような最初のタッチと最後のタッチの違いを測定します。

 @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if(e1.getY() > e2.getY()) //1
        {
            int pos=(int)Math.floor(listView.getLastVisiblePosition/2);//2
            if(pos < listView.getLastVisiblePosition())
                      listView.smoothScrollToPosition(pos--);//3
            else
                listView.smoothScrollToPosition(listView.getLastVisiblePosition());
        }
        else
        {
               int pos=(int)Math.floor(listView.getLastVisiblePosition/2);
            if(pos < listView.getLastVisiblePosition && pos > listView.getFirstVisiblePosition())
                      listView.smoothScrollToPosition(pos++);
                   else
                        listView.smoothScrollToPosition(listView.getFirstVisiblePosition());
        }                
    } 
  1. ife1.getY() > e2.getY()は、ユーザーが下向きに飛んだことを意味します。違いe2.getY() - e1.getY()は負です。

  2. 現在の位置が真ん中の位置であると仮定します。

  3. 1つの位置で下に移動します。

このコードはテストされておらず、3番目の質問への回答です。私はあなたに私の考えを指摘しているだけです。

于 2011-08-23T21:06:38.407 に答える
0

調査しながら、ページ付けを行うこのカスタムScrollViewを開発しました。

public class ScrollViewVertical extends ScrollView {private boolean paging;

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

public boolean onTouchEvent(MotionEvent evt) {
    if (evt.getAction() == MotionEvent.ACTION_UP)
        if (isPaging()){
            centralizeContent();
            return true;
        }

    return super.onTouchEvent(evt);
}

private void centralizeContent() {
    int currentY = getScrollY() + getHeight() / 2;
    ViewGroup content = (ViewGroup) getChildAt(0);
    for (int i = 0; i < content.getChildCount(); i++) {
        View child = content.getChildAt(i);
        System.out.println(BoundsUtils.from(child));
        if (child.getTop() < currentY && child.getBottom() > currentY) {
            smoothScrollTo(0, child.getTop());
            break;
        }
    }
}

}

于 2011-09-12T20:42:06.180 に答える