【问题标题】:Manipulating views of HorizontalScrollView操作 Horizo​​ntalScrollView 的视图
【发布时间】:2014-12-29 12:32:33
【问题描述】:

正如我在上一个问题 (Simple image gallery with HorizontalScrollView) 中所写,我使用 Horizo​​ntalScrollView 在一个简单的图片库中工作。现在我正在解决以下任务:要动态加载和显示图像,目标是在加载图像时必须在显示屏上显示进度条。所以我使用 android.os.AsyncTask 来加载图像。但起初我为添加和滚动图像制作了自定义水平滚动视图,目标方法是 processScroll,它是从 android.widget.Horizo​​ntalScrollView - android.lessons.custom_horizo​​ntal_scroll.ImageHorizo​​ntalScrollView#onFling 的公共方法调用的,它看起来像:

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    Log.d("IHSV", "GestureDetectorListener onFling event. " +
        "Info scrollX " + getScrollX() +
        " Info velocityX " + velocityX +
        " Info ev1X " + e1.getAxisValue(MotionEvent.AXIS_X) +
        " Info ev2X " + e2.getAxisValue(MotionEvent.AXIS_X));

    ev1X = (int) e1.getAxisValue(MotionEvent.AXIS_X);
    ev2X = (int) e2.getAxisValue(MotionEvent.AXIS_X);

    processScroll();

    return true;
}

而processScroll方法是

private void processScroll() {
    boolean isForward = ev1X > ev2X;
    boolean isPaging = isForward ? getImageSizeList().get(imageIndex)[0] / 2 >= ev2X :
        getImageSizeList().get(imageIndex)[0] / 2 <= ev2X;

    Log.d("IHSV", "processScroll imageIndex: " + imageIndex + " isForward: " + isForward + " isPaging: " + isPaging);

    if (isPaging) {
        boolean isSmoothScroll;
        // to page forward
        if (isForward) {
            isSmoothScroll = imageIndex + 1 != imageItems.length;
            imageIndex = ++imageIndex % imageItems.length;
        } else {
        // to page back
            isSmoothScroll = imageIndex - 1 >= 0;
            imageIndex = imageIndex - 1 < 0 ? imageItems.length - 1 : --imageIndex;
        }

        boolean isLoad = imageItems[imageIndex].isLoad;
        if (!imageItems[imageIndex].isLoad) {
            // show a progress bar 
            innerLayout.addView(getPbl());
        }

        if (isSmoothScroll) {
            if (isLoad) {
                smoothScrollTo(imageIndex * displayMetrics[0], 0);
            } else {
                innerLayout.scrollTo(imageIndex * displayMetrics[0], 0);
            }
        } else {
            scrollTo(imageIndex * displayMetrics[0], 0);
        }
        // load an image in the background task
        if (!imageItems[imageIndex].isLoad) {
            ImageLoaderTask imgLoader = new ImageLoaderTask(this, innerLayout);
            imgLoader.execute(imageItems[imageIndex].id);
        }
    } else {
        smoothScrollTo(imageIndex * displayMetrics[0], 0);
    }
}

在我制作加载图像之前您可以看到,我在内部布局(水平滚动视图的单个子项)中添加了一个进度条。 主要布局是

    <?xml version="1.0" encoding="utf-8"?>
    <android.lessons.custom_horizontal_scroll.ImageHorizontalScrollView
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/horizontalScrollView"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
<!-- **the inner layout** -->
        <LinearLayout android:orientation="horizontal"
                      android:id="@+id/mainLayout"
                      android:layout_width="wrap_content"
                      android:layout_height="match_parent">
        </LinearLayout>
</android.lessons.custom_horizontal_scroll.ImageHorizontalScrollView>

进度条布局是

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/progress_bar_layout"
             android:orientation="horizontal"
             android:layout_gravity="center"
             android:gravity="center"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content">
    <ProgressBar android:id="@+id/progress_bar"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"/>
</LinearLayout>

加载图片的任务是这样的

public class ImageLoaderTask extends AsyncTask<Integer, String, String> {


    @Override
    protected String doInBackground(Integer... params) {
       // load an image
    }

    @Override
    protected void onPostExecute(String result) {
        // remove the progess bar
        innerLayout.removeView(innerLayout.findViewById(R.id.progress_bar_layout));
        // add the load image
        innerLayout.addView(addImageView);
        ...
    }

}

我用下面的方法给进度条充气:

View getPbl() {
    if (pbl == null) {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService
            (Context.LAYOUT_INFLATER_SERVICE);

        pbl = inflater.inflate(R.layout.progress_bar, this, false);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(displayMetrics[0],
            displayMetrics[1]);

        lp.gravity = Gravity.FILL_HORIZONTAL | Gravity.CENTER_VERTICAL;
        pbl.setLayoutParams(lp);
    }
    return pbl;
}

那么让我们来回答问题: 1)我在 processScroll 方法中调用 innerLayout.scrollTo(...) 因为 android.widget.Horizo​​ntalScrollView#smoothScrollTo 不起作用:它不会滚动到进度条视图,为什么会这样那样做?图像加载后(ImageLoaderTask#onPostExecute 方法完成后)它会自行滚动。

2) 所以 innerLayout.scrollTo(...) 我得到了一个奇怪的行为:第一个滚动工作正常,下一个不添加图像它留下黑色空间: ) 在应该加载图像的位置。所以我认为 View#addView 和 View#removeView 不能正常工作,但是为什么呢?我应该调用水平滚动视图的任何刷新方法吗?

【问题讨论】:

    标签: java android xml view horizontalscrollview


    【解决方案1】:

    这很简单。我需要使用 View.onLayout 方法,该方法在添加视图后以小挂起方式调用。因为我重写了 Horizo​​ntalScrollView#onLayout 方法。

    【讨论】:

      猜你喜欢
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 2012-12-29
      • 2012-03-10
      • 1970-01-01
      相关资源
      最近更新 更多