Сделайте поведение ListView похожим на вертикальную галерею - PullRequest
0 голосов
/ 24 августа 2011

У меня есть следующий код, который заставляет 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 события: Они нужны мне, потому что я отправляю события в текущее представление и позволяю прокручивать ListView только тогда, когда currentView возвращает false для touchEvent, мне не нужны точно события ItemSelected, это может быть что-то похожее.
  • И еще один вопрос: если пользователь проведет пальцем вверх, я должен перевести только один вид (не несколько в зависимости от скорости жеста).

Любой компонент, который позволит мне это сделать, также будет полезным ответом.

EDIT: На самом деле, я решил эту проблему с помощью этого решения Использование анимации для прокрутки представлений , но я оставлю этот вопрос открытым.

Ответы [ 2 ]

0 голосов
/ 13 сентября 2011

Во время исследования я разработал этот пользовательский ScrollView, который выполняет нумерацию страниц.

открытый класс ScrollViewVertical extends ScrollView { приватный логический пейджинг;

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;
        }
    }
}

}

0 голосов
/ 24 августа 2011

как реализовать как касание, так и включение в одном и том же списке?

Прочтите этот вопрос, приняли ответ о реализации класса 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. , если e1.getY() > e2.getY() означает, что пользователь бросился вниз. Разница e2.getY() - e1.getY() отрицательна.

  2. Предположим, что текущая позиция является средней.

  3. Перемещение вниз на одну позицию.

Этот код не проверен и является ответом на ваш третий вопрос. Я просто указываю вам свою идею.

...