Domanda

I have the following code that make the ListView appears like a Vertical Gallery

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

But there's some behaviors that I need to simulate also:

  • Centralize a View: When a new view come, I need to centralize it on my display.
  • Fire onItemSelected events: I need those cause I dispatch events to the current view, and let the ListView scroll only when the currentView returns false on a touchEvent, I don't need exactly the ItemSelected events, this can be something similar.
  • And another question is, if the user swipe up, I should only translate one view (not several according to the speed of the gesture).

Any component that will let me do that will be a usefull answer also.

EDIT: Actually, I solved this problem with this solution Using Animation to swipe views but I'll keep this question open.

È stato utile?

Soluzione 2

As I research, I developed this custom ScrollView that does pagination.

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

}

Altri suggerimenti

how to implement both ontouch and also onfling in a same listview?

Read this question accepted answer about implementations of GestureListener class.

Make MyGestureListener class as inner in your current one or pass ListView object to the constructor of the MyGestureListener class.

In onFling() method measure the difference between initial and final touches like

 @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. if e1.getY() > e2.getY() means that user fling-ed downwards. The difference e2.getY() - e1.getY() is negative.

  2. Suppose that current position is the middle one.

  3. Moving downwards for one position.

This code isn't tested and is response to your 3rd question. I'm just pointing you my idea.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top