gpt4 book ai didi

android - android 是否具有等效的 UIScrollView?

转载 作者:太空宇宙 更新时间:2023-11-03 10:21:57 28 4
gpt4 key购买 nike

Android 中是否有 UIScrollView 的等效项,我可以在其中滑动图像。谢谢。

抱歉,我没有说得更具体。我需要向各个方向滑动。 Android 的 ScrollView 不会这样做。我一直在使用可以工作的 WebView,但它似乎只能在 4.0 及更高版本上工作。


这是我想到的。我将我的 ImageView 放在 WebView 中,并在 ImageView 上分配了 setOnTouchListener。它似乎运作良好。

  web = new WebView(this);
web.setVerticalScrollBarEnabled(false);
web.setHorizontalScrollBarEnabled(false);
web.setBackgroundColor(Color.RED);
web.setId(100);
RelativeLayout.LayoutParams layoutForContainer = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutForContainer.height = 300;
layoutForContainer.width = 300;
layoutForContainer.addRule(RelativeLayout.CENTER_IN_PARENT);
web.setLayoutParams(layoutForContainer);
layout.addView(web);

myImageView = new ImageView(this);
myImageView.setImageResource(R.drawable.myImage);
RelativeLayout.LayoutParams layoutForLargeImage = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutForLargeImage.height = (int) 768;
layoutForLargeImage.width = (int) 1024;
myImageView.setLayoutParams(layoutForLargeImage);
web.addView(myImageView);

myImageView.setOnTouchListener(new View.OnTouchListener() {
float downX, downY;
int scrollByX, scrollByY;
public boolean onTouch(View view, MotionEvent event) {
float currentX, currentY;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
currentX = event.getX();
currentY = event.getY();
scrollByX = (int)(downX - currentX);
scrollByY = (int)(downY - currentY);

myImageView.scrollBy(scrollByX, scrollByY);
downX = currentX;
downY = currentY;

break;
}
return true;
}
});

最佳答案

这个问题已经有将近一年的历史了,但它在谷歌搜索中排在首位,所以我想我应该添加一些细节。

如果您正在寻找可以滚动的通用单向 View ,使用 Android 内置的 ScrollView 的其他答案会很好。

但是,如果您想要 iOS 的 UIScrollView 的多向方面,则必须设计/使用自定义 View (或使用 hack,例如使用 webview)。可以在此处的相关问题中找到可以执行此操作的 View 的示例实现:

View with horizontal and vertical pan/drag and pinch-zoom

然后根据你的喜好,你可以根据需要修改它,比如这个没有缩放(只是平移)的实现:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.view.*;

public class MultiDirectionPanGroup extends ViewGroup {

private static final int INVALID_POINTER_ID = 1;
private int mActivePointerId = INVALID_POINTER_ID;

private float mPosX;
private float mPosY;
private Matrix mTranslateMatrix = new Matrix();
private Matrix mTranslateMatrixInverse = new Matrix();

private float mLastTouchX;
private float mLastTouchY;

private float mFocusY;

private float mFocusX;

private float[] mInvalidateWorkingArray = new float[6];
private float[] mDispatchTouchEventWorkingArray = new float[2];
private float[] mOnTouchEventWorkingArray = new float[2];


public MultiDirectionPanGroup(Context context) {
super(context);
mTranslateMatrix.setTranslate(0, 0);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
child.layout(l, t, l+child.getMeasuredWidth(), t + child.getMeasuredHeight());
}
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}
}

@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
canvas.translate(mPosX, mPosY);
super.dispatchDraw(canvas);
canvas.restore();
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
mDispatchTouchEventWorkingArray[0] = ev.getX();
mDispatchTouchEventWorkingArray[1] = ev.getY();
mDispatchTouchEventWorkingArray = screenPointsToScaledPoints(mDispatchTouchEventWorkingArray);
ev.setLocation(mDispatchTouchEventWorkingArray[0],
mDispatchTouchEventWorkingArray[1]);
return super.dispatchTouchEvent(ev);
}

/**
* Although the docs say that you shouldn't override this, I decided to do
* so because it offers me an easy way to change the invalidated area to my
* likening.
*/
@Override
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {

mInvalidateWorkingArray[0] = dirty.left;
mInvalidateWorkingArray[1] = dirty.top;
mInvalidateWorkingArray[2] = dirty.right;
mInvalidateWorkingArray[3] = dirty.bottom;


mInvalidateWorkingArray = scaledPointsToScreenPoints(mInvalidateWorkingArray);
dirty.set(Math.round(mInvalidateWorkingArray[0]), Math.round(mInvalidateWorkingArray[1]),
Math.round(mInvalidateWorkingArray[2]), Math.round(mInvalidateWorkingArray[3]));

location[0] *= mScaleFactor;
location[1] *= mScaleFactor;
return super.invalidateChildInParent(location, dirty);
}

private float[] scaledPointsToScreenPoints(float[] a) {
mTranslateMatrix.mapPoints(a);
return a;
}

private float[] screenPointsToScaledPoints(float[] a){
mTranslateMatrixInverse.mapPoints(a);
return a;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
mOnTouchEventWorkingArray[0] = ev.getX();
mOnTouchEventWorkingArray[1] = ev.getY();

mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray);

ev.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]);

final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();

mLastTouchX = x;
mLastTouchY = y;

// Save the ID of this pointer
mActivePointerId = ev.getPointerId(0);
break;
}

case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);

final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;

mPosX += dx;
mPosY += dy;
mTranslateMatrix.preTranslate(dx, dy);
mTranslateMatrix.invert(mTranslateMatrixInverse);

mLastTouchX = x;
mLastTouchY = y;

invalidate();
break;
}

case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}

case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}

case MotionEvent.ACTION_POINTER_UP: {
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}

}

关于android - android 是否具有等效的 UIScrollView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19043830/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com