Android:在从HorizontalScrollView创建的自定义类上分页是不平滑的

Android:在从HorizontalScrollView创建的自定义类上分页是不平滑的,android,horizontalscrollview,pager,infinite,Android,Horizontalscrollview,Pager,Infinite,我试图从水平滚动视图创建一个无限寻呼机 它会根据需要不断重新排列子视图,从而实现无限滚动,但一旦必须开始移动视图(添加到左侧或右侧),它就不再平滑滚动。我试图找出如何让它滚动到下一页顺利,即使它改变了子位置 以下是我目前掌握的课程: import java.util.HashMap; import java.util.Map; import android.content.Context; import android.util.AttributeSet; import android.uti

我试图从水平滚动视图创建一个无限寻呼机

它会根据需要不断重新排列子视图,从而实现无限滚动,但一旦必须开始移动视图(添加到左侧或右侧),它就不再平滑滚动。我试图找出如何让它滚动到下一页顺利,即使它改变了子位置

以下是我目前掌握的课程:

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

public class PagerInfinite extends HorizontalScrollView {
    private LinearLayout contents;
    private Map<Integer, Integer> childWidths =  new HashMap<Integer, Integer>();
    private int childSpacing = 0;
    private int activePageIndex = 1;
    private float oldX = 0f;
    private float oldY = 0f;
    private boolean firstScroll = true;

public PagerInfinite(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.contents = new LinearLayout(context);
    this.contents.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));
    this.addView(this.contents);
    setVerticalScrollBarEnabled(false);
    setHorizontalScrollBarEnabled(false);
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    for (int i = 0; i < this.contents.getChildCount(); i++) {
        View child = this.contents.getChildAt(i);
        int width = child.getWidth();
        if(width != 0) {
            this.childWidths.put(i, width);
        }
    }
    if(this.childWidths.size() > 0 && this.firstScroll) {
        this.smoothScrollTo(this.getActivePageOffset(), 0);
        this.firstScroll = false;
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected float getLeftFadingEdgeStrength() {
    return 0.0f;
}

@Override
protected float getRightFadingEdgeStrength() {
    return 0.0f;
}

public void addPage(View child) {
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    params.setMargins(0, 0, this.childSpacing, 0);
    child.setLayoutParams(params);
    if(this.contents.getChildCount() <= 1) {
        this.contents.addView(child);
    } else if(this.contents.getChildCount() <= 2) {
        this.contents.addView(child, 0);
    } else {
        View last = this.contents.getChildAt(0);
        this.contents.removeView(last);
        this.contents.addView(last);
        this.contents.addView(child, 0);
    }
    this.contents.requestLayout();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean result = super.onTouchEvent(event);

    switch(event.getAction()) {
        case(MotionEvent.ACTION_DOWN):
            this.oldX = event.getX();
            this.oldY = event.getY();
            break;
        case(MotionEvent.ACTION_UP):
            float newX = event.getX();
            float newY = event.getY();
            float deltaX = newX - this.oldX;
            float deltaY = newY - this.oldY;

            // Use deltaX and deltaY to determine the direction
            if(Math.abs(deltaX) > Math.abs(deltaY)) {
                if(deltaX > 0) {
                    // right
                    if(this.activePageIndex <= 1) {
                        this.buildLeft();
                    } else {
                        this.activePageIndex -= 1;
                    }
                } else {
                    // left
                    if(this.activePageIndex >= this.contents.getChildCount() - 2) {
                        this.buildRight();
                    } else {
                        this.activePageIndex += 1;
                    }
                }
            }
            this.smoothScrollTo(this.getActivePageOffset(), 0);
            break;
    }

    return result;
}

private void buildLeft() {
    View view = this.contents.getChildAt(this.contents.getChildCount() - 1);
    this.contents.removeView(view);
    this.contents.addView(view, 0);
}

private void buildRight() {
    View view = this.contents.getChildAt(0);
    this.contents.removeView(view);
    this.contents.addView(view);
}

private int getActivePageOffset() {
    Log.d(LCHApplication.TAG, "ActiveIndex = " + this.activePageIndex);
    if(this.activePageIndex == 0) {
        return 0;
    }
    if(this.activePageIndex == this.contents.getChildCount() - 1) {
        return this.contents.getWidth();
    }
    int offset = 0;
    for(Map.Entry<Integer, Integer> entry : this.childWidths.entrySet()) {
        if(entry.getKey() < this.activePageIndex) {
            offset += entry.getValue() + this.childSpacing;
        } else {
            break;
        }
    }
    offset += (this.childWidths.get(this.activePageIndex) / 2);
    offset -= (LCHApplication.instance.width / 2);
    return offset;
}

public boolean hasPage(View v) {
    return this.contents.indexOfChild(v) != -1;
}

public void removePage(View v) {
    int index = this.contents.indexOfChild(v);
    this.contents.removeView(v);
    this.childWidths.remove(index);
}

public int getCurrentPageIndex() {
    return this.activePageIndex;
}

public int getPageCount() {
    return this.contents.getChildCount();
}

public void removeAllPages() {
    this.contents.removeAllViews();
    this.childWidths = new HashMap<Integer, Integer>();
}

public void cycle() {
    if(this.activePageIndex < this.contents.getChildCount() - 1) {
        this.activePageIndex += 1;
    } else {
        this.activePageIndex = 0;
    }
    this.smoothScrollTo(this.getActivePageOffset(), 0);
}

public int getChildSpacing() {
    return this.childSpacing;
}

public void setChildSpacing(int spacing) {
    this.childSpacing = spacing;
}
}
import java.util.HashMap;
导入java.util.Map;
导入android.content.Context;
导入android.util.AttributeSet;
导入android.util.Log;
导入android.view.MotionEvent;
导入android.view.view;
导入android.widget.HorizontalScrollView;
导入android.widget.LinearLayout;
公共类PagerInfinite扩展水平滚动视图{
私人线路布置内容;
private Map childWidths=新HashMap();
私有int-childSpacing=0;
private int activePageIndex=1;
私有浮动oldX=0f;
私有浮动oldY=0f;
private boolean firstScroll=true;
公共页面有限(上下文、属性集属性){
超级(上下文,attrs);
this.contents=新的线性布局(上下文);
this.contents.setLayoutParams(新的LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.FILL_PARENT));
this.addView(this.contents);
setVerticalScrollBarEnabled(假);
setHorizontalScrollBarEnabled(假);
}
@凌驾
测量时的公共空隙(int-widthMeasureSpec,int-heightMeasureSpec){
for(int i=0;i0&&this.firstScroll){
this.smoothScrollTo(this.getActivePageOffset(),0);
this.firstScroll=false;
}
超级测量(宽度测量、高度测量);
}
@凌驾
受保护的浮点getLeftFadingEdgeStrength(){
返回0.0f;
}
@凌驾
受保护的浮点getRightFadingEdgeStrength(){
返回0.0f;
}
公共无效添加页(查看子项){
LinearLayout.LayoutParams params=新的LinearLayout.LayoutParams(LayoutParams.WRAP\u内容,LayoutParams.WRAP\u内容);
参数setMargins(0,0,this.childSpacing,0);
setLayoutParams(params);
if(this.contents.getChildCount()0){
//对
if(this.activePageIndex=this.contents.getChildCount()-2){
this.buildRight();
}否则{
this.activePageIndex+=1;
}
}
}
this.smoothScrollTo(this.getActivePageOffset(),0);
打破
}
返回结果;
}
私有void buildLeft(){
视图=this.contents.getChildAt(this.contents.getChildCount()-1);
this.contents.removeView(视图);
this.contents.addView(视图,0);
}
私人建筑权(){
View=this.contents.getChildAt(0);
this.contents.removeView(视图);
this.contents.addView(视图);
}
私有int getActivePageOffset(){
Log.d(LCHApplication.TAG,“ActiveIndex=“+this.activePageIndex”);
if(this.activePageIndex==0){
返回0;
}
if(this.activePageIndex==this.contents.getChildCount()-1){
返回此.contents.getWidth();
}
整数偏移=0;
对于(Map.Entry:this.childWidths.entrySet()){
if(entry.getKey()
虽然为时已晚,但我相信我的回答可能会对其他有同样问题的人有所帮助

具有无限页面的示例项目-具有页面滑动效果