Horizontal List View Scrolling is not smooth in android

淺唱寂寞╮ 提交于 2020-01-15 09:11:14

问题


I have used lazy loading to download the images and thus populate in horizontal list view. But scrolling is not smooth, specially when scrolling from right to left end. These are my codes:

homepg.xml

<ScrollView
            android:id="@+id/scrollView1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:scrollbars="none" >

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" > 

<RelativeLayout
                    android:id="@+id/Horizlistlatestnews"
                    android:layout_width="match_parent"
                    android:layout_height="105dp"
                      android:orientation="horizontal"
                      android:layout_below="@+id/Titlelatestnews"
                     >                   
                  <com.xxx.xxx.HorizontalView
            android:id="@+id/horizontallistln"
            android:layout_width="match_parent"
            android:layout_height="match_parent"  
            android:layout_marginLeft="2dp"         
            android:scrollbars="none"  


             >
        </com.xxx.xxx.HorizontalView>

                        </RelativeLayout>
                    </RelativeLayout>
                          <RelativeLayout
                    android:id="@+id/Boxoffice"
                    android:layout_width="match_parent"
                    android:layout_height="145dp"   
                    android:background="@drawable/bggray" >

                    <RelativeLayout
                    android:id="@+id/Titleboxofc"
                    android:layout_width="match_parent"
                    android:layout_height="30dp"                   

                     >

                        <TextView
                            android:id="@+id/textViewboxofc"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="BOX OFFICE"
                            android:textColor="#FFFFFF"
                            android:textStyle="bold"
                            android:layout_alignParentLeft="true"
                            android:layout_marginLeft="5dp"
                            android:layout_centerVertical="true" />
                        <ProgressBar
                            android:id="@+id/progressBarboxofc"
                            android:layout_width="15dp"
                            android:layout_height="15dp"                            
                            android:visibility="gone"
                            android:layout_alignParentRight="true"
                            android:layout_marginRight="10dp"
                            android:layout_centerVertical="true"
                            />

                    </RelativeLayout>
                     <RelativeLayout
                    android:id="@+id/Horizlistboxofc"
                    android:layout_width="match_parent"
                    android:layout_height="105dp"
                      android:orientation="horizontal"
                      android:layout_below="@+id/Titleboxofc"
                     >                   
                  <com.xxx.xxx.HorizontalView
            android:id="@+id/horizontallistbo"
            android:layout_width="match_parent"
            android:layout_height="match_parent"  
            android:layout_marginLeft="2dp"         
            android:scrollbars="none"       

             >
        </com.xxx.xxx.HorizontalView>

                        </RelativeLayout>

 </LinearLayout>
        </ScrollView>

HorizontalView.java

package com.xxx.xxx;

import java.util.LinkedList;
import java.util.Queue;

import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;

public class HorizontalView extends AdapterView<Adapter> {

    public boolean mAlwaysOverrideTouch = true;
    protected ListAdapter mAdapter;
    private int mLeftViewIndex = -1;
    private int mRightViewIndex = 0;
    protected int mCurrentX;
    protected int mNextX;
    private int mMaxX = Integer.MAX_VALUE;
    private int mDisplayOffset = 0;
    protected Scroller mScroller;
    private GestureDetector mGesture;
    private Queue mRemovedViewQueue = new LinkedList();
    private OnItemSelectedListener mOnItemSelected;
    private OnItemClickListener mOnItemClicked;
    private OnItemLongClickListener mOnItemLongClicked;
    private boolean mDataChanged = false;

    public HorizontalView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private synchronized void initView() {
        mLeftViewIndex = -1;
        mRightViewIndex = 0;
        mDisplayOffset = 0;
        mCurrentX = 0;
        mNextX = 0;
        mMaxX = Integer.MAX_VALUE;
        mScroller = new Scroller(getContext());
        mGesture = new GestureDetector(getContext(), mOnGesture);
    }

    @Override
    public void setOnItemSelectedListener(
            AdapterView.OnItemSelectedListener listener) {
        mOnItemSelected = listener;
    }

    @Override
    public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
        mOnItemClicked = listener;
    }

    @Override
    public void setOnItemLongClickListener(
            AdapterView.OnItemLongClickListener listener) {
        mOnItemLongClicked = listener;
    }

    private DataSetObserver mDataObserver = new DataSetObserver() {

        @Override
        public void onChanged() {
            synchronized (HorizontalView.this) {
                mDataChanged = true;
            }
            invalidate();
            requestLayout();
        }

        @Override
        public void onInvalidated() {
            reset();
            invalidate();
            requestLayout();
        }

    };

    @Override
    public Adapter getAdapter() {
        return mAdapter;
    }

    @Override
    public View getSelectedView() {
        return null;
    }

    @Override
    public void setAdapter(Adapter adapter) {
        if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mDataObserver);
        }
        mAdapter = (ListAdapter) adapter;
        mAdapter.registerDataSetObserver(mDataObserver);
        reset();
    }

    private synchronized void reset() {
        initView();
        removeAllViewsInLayout();
        requestLayout();
    }

    @Override
    public void setSelection(int position) {

    }

    private void addAndMeasureChild(final View child, int viewPos) {
        LayoutParams params = child.getLayoutParams();
        if (params == null) {
            params = new LayoutParams(LayoutParams.FILL_PARENT,
                    LayoutParams.FILL_PARENT);
        }

        addViewInLayout(child, viewPos, params, true);
        child.measure(
                MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
                MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
    }

    @Override
    protected synchronized void onLayout(boolean changed, int left, int top,
            int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        if (mAdapter == null) {
            return;
        }

        if (mDataChanged) {
            int oldCurrentX = mCurrentX;
            initView();
            removeAllViewsInLayout();
            mNextX = oldCurrentX;
            mDataChanged = false;
        }

        if (mScroller.computeScrollOffset()) {
            int scrollx = mScroller.getCurrX();
            mNextX = scrollx;
        }

        if (mNextX <= 0) {
            mNextX = 0;
            mScroller.forceFinished(true);
        }
        if (mNextX >= mMaxX) {
            mNextX = mMaxX;
            mScroller.forceFinished(true);
        }

        int dx = mCurrentX - mNextX;

        // removeNonVisibleItems(dx);
        fillList(dx);
        positionItems(dx);

        mCurrentX = mNextX;

        if (!mScroller.isFinished()) {
            post(new Runnable() {
                @Override
                public void run() {
                    requestLayout();
                }
            });

        }
    }

    private void fillList(final int dx) {
        int edge = 0;
        View child = getChildAt(getChildCount() - 1);
        if (child != null) {
            edge = child.getRight();
        }
        fillListRight(edge, dx);

        edge = 0;
        child = getChildAt(0);
        if (child != null) {
            edge = child.getLeft();
        }
        fillListLeft(edge, dx);
    }

    private void fillListRight(int rightEdge, final int dx) {
        while (rightEdge + dx < getWidth()
                && mRightViewIndex < mAdapter.getCount()) {

            View child = mAdapter.getView(mRightViewIndex,
                    (View) mRemovedViewQueue.poll(), this);
            addAndMeasureChild(child, -1);
            rightEdge += child.getMeasuredWidth();

            if (mRightViewIndex == mAdapter.getCount() - 1) {
                mMaxX = mCurrentX + rightEdge - getWidth();
            }

            if (mMaxX < 0) {
                mMaxX = 0;
            }
            mRightViewIndex++;
        }

    }

    private void fillListLeft(int leftEdge, final int dx) {
        while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {
            View child = mAdapter.getView(mLeftViewIndex,
                    (View) mRemovedViewQueue.poll(), this);
            addAndMeasureChild(child, 0);
            leftEdge -= child.getMeasuredWidth();
            mLeftViewIndex--;
            mDisplayOffset -= child.getMeasuredWidth();
        }
    }

    private void positionItems(final int dx) {
        if (getChildCount() > 0) {
            mDisplayOffset += dx;
            int left = mDisplayOffset;
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                int childWidth = child.getMeasuredWidth();
                child.layout(left, 0, left + childWidth,
                        child.getMeasuredHeight());
                left += childWidth;
            }
        }
    }

    public synchronized void scrollTo(int x) {
        mScroller.startScroll(mNextX, 0, x - mNextX, 0);
        requestLayout();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean handled = super.dispatchTouchEvent(ev);
        handled |= mGesture.onTouchEvent(ev);
        return handled;
    }

    protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        synchronized (HorizontalView.this) {
            mScroller.fling(mNextX, 0, (int) -velocityX, 0, 0, mMaxX, 0, 0);
        }
        requestLayout();

        return true;
    }

    protected boolean onDown(MotionEvent e) {
        mScroller.forceFinished(true);
        return true;
    }

    private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {

        public boolean onDown(MotionEvent e) {
            return HorizontalView.this.onDown(e);
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            return HorizontalView.this.onFling(e1, e2, velocityX, velocityY);
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY) {
            synchronized (HorizontalView.this) {
                mNextX += (int) distanceX;
            }
            requestLayout();
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                if (isEventWithinView(e, child)) {
                    if (mOnItemClicked != null) {
                        mOnItemClicked.onItemClick(HorizontalView.this, child,
                                mLeftViewIndex + 1 + i,
                                mAdapter.getItemId(mLeftViewIndex + 1 + i));
                    }
                    if (mOnItemSelected != null) {
                        mOnItemSelected.onItemSelected(HorizontalView.this,
                                child, mLeftViewIndex + 1 + i,
                                mAdapter.getItemId(mLeftViewIndex + 1 + i));
                    }
                    break;
                }
            }
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if (isEventWithinView(e, child)) {
                    if (mOnItemLongClicked != null) {
                        mOnItemLongClicked.onItemLongClick(HorizontalView.this,
                                child, mLeftViewIndex + 1 + i,
                                mAdapter.getItemId(mLeftViewIndex + 1 + i));
                    }
                    break;
                }
            }
        }

        private boolean isEventWithinView(MotionEvent e, View child) {
            Rect viewRect = new Rect();
            int[] childPosition = new int[2];
            child.getLocationOnScreen(childPosition);
            int left = childPosition[0];
            int right = left + child.getWidth();
            int top = childPosition[1];
            int bottom = top + child.getHeight();
            viewRect.set(left, top, right, bottom);
            return viewRect.contains((int) e.getRawX(), (int) e.getRawY());
        }
    };


}

HorizontalImageAdapter.java

package com.xxx.xxx;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ImageView.ScaleType;

public class HorizontalImageAdapter extends ArrayAdapter<RSSItem> {

    //private Context context;
            private List<RSSItem> objectsln = new ArrayList<RSSItem>();
            int ResourceId;
            private Activity activity;
            public ImageManager imageManager1;

    private static ViewHolder holder;


    public HorizontalImageAdapter(Activity a, int textViewResourceId, List<RSSItem> objectsln) {

        super(a, textViewResourceId, objectsln);
        System.out.println("LISTVIEW Constructor Called");
        activity = a;
        this.objectsln = objectsln;
        this.ResourceId = textViewResourceId;
        imageManager1 = new ImageManager(activity.getApplicationContext());
    }

    @Override
    public int getCount() {
        return this.objectsln.size();
    }

    @Override
    public RSSItem getItem(int position) {
        return this.objectsln.get(position);

    }

    @Override
    public long getItemId(int position) {
        System.out.println("LISTVIEW POSITION Called: "+position);
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            holder = new ViewHolder();
             LayoutInflater infleter = (LayoutInflater) this.getContext().getSystemService(Context.
                       LAYOUT_INFLATER_SERVICE);
             convertView = infleter.inflate(ResourceId, parent, false);         
            holder = new ViewHolder();
            holder.imageViewln = (ImageView) convertView.findViewById(R.id.imageViewhlist);
            holder.textviewln=(TextView)convertView.findViewById(R.id.textViewhlist);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        RSSItem dataln = null ;

            //get the item
            if(objectsln.size() !=0){
                dataln = getItem(position);
            }else{
                Log.i("test TAG", "Size zero found");
            }

            if (dataln != null) {
                holder.textviewln.setText(dataln.title); // For taking the title from
                                                    // Web Services and set into text view
                System.out.println("TITLE LATEST NEWS - "+position+": "+dataln.title);  

                holder.imageViewln.setScaleType(ScaleType.FIT_XY);

                holder.imageViewln.setTag(dataln.imageurl);
                imageManager1.displayImage(dataln.imageurl, activity,
                        holder.imageViewln);
            }
        return convertView;
    }

    private static class ViewHolder {
        ImageView imageViewln;
        TextView textviewln;
    }

}

来源:https://stackoverflow.com/questions/17119991/horizontal-list-view-scrolling-is-not-smooth-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!