我正在使用chrisbanes PhotoView来实现捏缩放..图像缩放捏和双击但我无法看到我的图像在变焦时拉伸到全屏...缩放它看起来图像放大到框内和部分图像的缩放在缩放时消失...我如何实现图像缩放,以便在缩放时图像的高度增加?我正在使用NetworkImageView(Volley库)。
NetworkImageView imageView;
PhotoViewAttacher mAttacher;
imageView = (NetworkImageView) mImgPagerView.findViewById(R.id.imageitem);
mAttacher = new PhotoViewAttacher(imageView);
NetworkImageView.java(Volley库)
import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.android.volley.toolbox.ImageLoader.ImageContainer;
public class NetwrokImageView extends ImageView {
/** The URL of the network image to load */
private String mUrl;
/**
* Resource ID of the image to be used as a placeholder until the network image is loaded.
*/
private int mDefaultImageId;
/**
* Resource ID of the image to be used if the network response fails.
*/
private int mErrorImageId;
/** Local copy of the ImageLoader. */
private ImageLoader mImageLoader;
public NetworkImageView(Context context) {
this(context, null);
}
public NetworkImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public NetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets URL of the image that should be loaded into this view. Note that calling this will
* immediately either set the cached image (if available) or the default image specified by
* {@link NetworkImageView#setDefaultImageResId(int)} on the view.
*
* NOTE: If applicable, {@link NetworkImageView#setDefaultImageResId(int)} and
* {@link NetworkImageView#setErrorImageResId(int)} should be called prior to calling
* this function.
*
* @param url The URL that should be loaded into this ImageView.
* @param imageLoader ImageLoader that will be used to make the request.
*/
public void setImageUrl(String url, ImageLoader imageLoader) {
mUrl = url;
mImageLoader = imageLoader;
// The URL has potentially changed. See if we need to load it.
loadImageIfNecessary();
}
/**
* Sets the default image resource ID to be used for this view until the attempt to load it
* completes.
*/
public void setDefaultImageResId(int defaultImage) {
mDefaultImageId = defaultImage;
}
/**
* Sets the error image resource ID to be used for this view in the event that the image
* requested fails to load.
*/
public void setErrorImageResId(int errorImage) {
mErrorImageId = errorImage;
}
/**
* Loads the image for the view if it isn't already loaded.
*/
private void loadImageIfNecessary() {
int width = getWidth();
int height = getHeight();
// if the view's bounds aren't known yet, hold off on loading the image.
if (width == 0 && height == 0) {
return;
}
// if the URL to be loaded in this view is empty, cancel any old requests and clear the
// currently loaded image.
if (TextUtils.isEmpty(mUrl)) {
ImageContainer oldContainer = (ImageContainer) getTag();
if (oldContainer != null) {
oldContainer.cancelRequest();
setImageBitmap(null);
}
return;
}
ImageContainer oldContainer = (ImageContainer) getTag();
// if there was an old request in this view, check if it needs to be canceled.
if (oldContainer != null && oldContainer.getRequestUrl() != null) {
if (oldContainer.getRequestUrl().equals(mUrl)) {
// if the request is from the same URL, return.
return;
} else {
// if there is a pre-existing request, cancel it if it's fetching a different URL.
oldContainer.cancelRequest();
setImageBitmap(null);
}
}
// The pre-existing content of this view didn't match the current URL. Load the new image
// from the network.
ImageContainer newContainer = mImageLoader.get(mUrl,
ImageLoader.getImageListener(this, mDefaultImageId, mErrorImageId));
// update the tag to be the new bitmap container.
setTag(newContainer);
// look at the contents of the new container. if there is a bitmap, load it.
final Bitmap bitmap = newContainer.getBitmap();
if (bitmap != null) {
setImageBitmap(bitmap);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
loadImageIfNecessary();
}
@Override
protected void onDetachedFromWindow() {
ImageContainer oldContainer = (ImageContainer) getTag();
if (oldContainer != null) {
// If the view was bound to an image request, cancel it and clear
// out the image from the view.
oldContainer.cancelRequest();
setImageBitmap(null);
// also clear out the tag so we can reload the image if necessary.
setTag(null);
}
super.onDetachedFromWindow();
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
invalidate();
}
}
的build.gradle
compile 'com.github.chrisbanes.photoview:library:+'
XML
<com.xyz.NetworkImageView
android:id="@+id/imageitem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="matrix"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:background="@drawable/image_loading" />
ImageView位于FrameLayout
中 <FrameLayout
android:id="@+id/image_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@color/black"
>
缩放前的图像 缩放后的图像
答案 0 :(得分:1)
如果你陷入困境,最好尝试不同的方法
您可以在下面找到由Jason Polites创建的类的链接,该类允许您处理自定义ImageView上的缩放缩放:https://github.com/jasonpolites/gesture-imageview。
只需将此软件包包含到您的应用程序中,然后您就可以在XML文件中使用自定义GestureImaveView
:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gesture-image="http://schemas.polites.com/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.polites.android.GestureImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/image"
gesture-image:min-scale="0.1"
gesture-image:max-scale="10.0"
gesture-image:strict="false"/>
此类处理缩放缩放,但也可以双击。
答案归功于Yoann:)
答案 1 :(得分:1)
我强烈建议您查看照片视图:
https://github.com/chrisbanes/PhotoView
它是由Chris Banes开发的,他是开发Android开发团队的实际开发人员之一,所以你不会在这里出错。这个库可以为您节省很多麻烦。
用法很简单:
ImageView mImageView;
PhotoViewAttacher mAttacher;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Any implementation of ImageView can be used!
mImageView = (ImageView) findViewById(R.id.iv_photo);
// Set the Drawable displayed
Drawable bitmap = getResources().getDrawable(R.drawable.wallpaper);
mImageView.setImageDrawable(bitmap);
// Attach a PhotoViewAttacher, which takes care of all of the zooming functionality.
mAttacher = new PhotoViewAttacher(mImageView);
}
答案 2 :(得分:1)
我在github上创建了一个功能齐全的项目。链接在答案的最后。
问题元素:
1。获取触摸事件并使用它的变量来设置图像缩放级别和窗口。 (左,上,右,下)。
示例代码:一次只显示部分图片。因此设置android:scaleType="fitCenter"
将实现缩放。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/imageFrameLayout"
android:background="@android:color/black">
<ImageView android:id="@+id/imageView"
android:layout_width="0px"
android:layout_height="0px"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:background="@android:color/transparent" />
</FrameLayout>
触摸侦听器(您可以修改此选项以添加点击事件)
OnTouchListener MyOnTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
float distx, disty;
switch(event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
//A pressed gesture has started, the motion contains the initial starting location.
touchState = TOUCH;
currentX = (int) event.getRawX();
currentY = (int) event.getRawY();
break;
case MotionEvent.ACTION_POINTER_DOWN:
//A non-primary pointer has gone down.
touchState = PINCH;
//Get the distance when the second pointer touch
distx = event.getX(0) - event.getX(1);
disty = event.getY(0) - event.getY(1);
dist0 = (float) Math.sqrt(distx * distx + disty * disty);
distLast = dist0;
break;
case MotionEvent.ACTION_MOVE:
//A change has happened during a press gesture (between ACTION_DOWN and ACTION_UP).
if(touchState == PINCH){
// pinch started calculate scale step.
//Get the current distance
distx = event.getX(0) - event.getX(1);
disty = event.getY(0) - event.getY(1);
distCurrent = (float) Math.sqrt(distx * distx + disty * disty);
if (Math.abs(distCurrent-distLast) >= 35) // check sensitivity
{
stepScale = distCurrent/dist0;
distLast = distCurrent;
drawMatrix(); // draw new image
}
}
else
{
// move started.
if (currentX==-1 && currentY==-1)
{
// first move after touch down
currentX = (int) event.getRawX();
currentY = (int) event.getRawY();
}
else
{
// calculate move window variable.
int x2 = (int) event.getRawX();
int y2 = (int) event.getRawY();
int dx = (currentX - x2);
int dy = (currentY - y2);
left += dx;
top += dy;
currentX = x2;
currentY = y2;
drawMatrix(); // draw new image window
}
}
break;
case MotionEvent.ACTION_UP:
//A pressed gesture has finished.
touchState = IDLE;
break;
case MotionEvent.ACTION_POINTER_UP:
//A non-primary pointer has gone up.
if (touchState == PINCH)
{
// pinch ended. reset variable.
}
touchState = TOUCH;
break;
}
return true;
}
};
2。由于需要缩放。我假设我们正在使用高质量的图像。
因此,在缩小时加载全尺寸质量图像不会带来好处,因为用户不会识别小细节。但它会增加内存使用量,并且可能会因非常大的图像而崩溃。
解决方案技巧:在缩小加载较大窗口时降低质量。 放大加载较小窗口,质量更高。
建议的解决方案检查所需的当前缩放级别和图像窗口,并根据该窗口仅使用 BitmapRegionDecoder 和 BitmapFactory 获得具有特定质量的图像的一部分。
示例代码:
初始化图像解码器,稍后将用于询问图像的一部分:
InputStream is = null;
bitmapRegionDecoder = null;
try {
is = getAssets().open(res_id); // get image stream from assets. only the stream, no mem usage
bitmapRegionDecoder = BitmapRegionDecoder.newInstance(is, false);
} catch (IOException e) {
e.printStackTrace();
}
bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true; // only specs needed. no image yet!
BitmapFactory.decodeStream(is, null, bounds); // get image specs.
try {
is.close(); // close stream no longer needed.
} catch (IOException e) {
e.printStackTrace();
}
要求图像质量和窗口:
Rect pRect = new Rect(left, top, left + newWidth, top + newHeight);
BitmapFactory.Options bounds = new BitmapFactory.Options();
int inSampleSize = 1;
if (tempScale <= 2.75) // you can map scale with quality better than this.
inSampleSize = 2;
bounds.inSampleSize = inSampleSize; // set image quality. takes binary steps only. 1, 2, 4, 8 . .
bm = bitmapRegionDecoder.decodeRegion(pRect, bounds);
imageView.setImageBitmap(bm);
答案 3 :(得分:1)
我在照片查看图像缩放库中遇到了这个问题。我已将layout_height从“ wrap_content”更改为“ match_parent”。它对我来说很好。
https://github.com/chrisbanes/PhotoView
<com.xyz.NetworkImageView
android:id="@+id/imageitem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:background="@drawable/image_loading" />
答案 4 :(得分:0)
如果您希望更改ImageView的大小,则需要更改其layoutParams,因为我已经演示了here。你也可以改变它的规模,从Honeycomb。
但是,如果你想在图像中移动一个矩形,它也可以很好地缩放(就像其他允许裁剪的应用程序一样),你可以使用像"cropper&#34;这样的库。或者,如果您不需要这些功能,可以使用TouchImageView
等库答案 5 :(得分:0)
这是因为ImageView的视图高度为“wrap_content”。将其更改为“match_parent”并将图像的scaleType设置为“centerInside”以解决您的问题。
答案 6 :(得分:0)
问题在于,当使用NetworkImageView的行为与ImageView不同时,我通过为纵向和横向创建xml设计来解决它
<强>纵向强>
<强>布局/ item_image.xml 强>
height =“match_parent”和width =“wrap_content”,重要 scaleType =“fitCenter”
<com.android.volley.toolbox.NetworkImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:background="@android:color/transparent"
android:id="@+id/imageitem"/>
<强> LAND 强>
<强>布局/土地/ item_image.xml 强>
现在在土地布局中,height =“wrap_content”和width =“match_parent”,总是 scaleType =“fitCenter”
<com.android.volley.toolbox.NetworkImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:background="@android:color/transparent"
android:id="@+id/imageitem"/>
在将资源分配给NetworkImageView控件后实例化PhotoViewAttacher对象也很重要
NetworkImageView imageView;
PhotoViewAttacher mAttacher;
imageView = (NetworkImageView)
mImgPagerView.findViewById(R.id.imageitem);
//firts set the image resources, i'm using Android Volley Request
ImageLoader imageLoader = MySocialMediaSingleton.getInstance(context).getImageLoader();
imageView.setImageUrl(url, imageLoader);
//next create instance of PhotoViewAttecher
mAttacher = new PhotoViewAttacher(imageView);
mAttacher.update();
答案 7 :(得分:0)
我使用imageviewtouch并遇到相同的问题。为了解决这个问题,您可以将imageview包装在布局内,而无需任何其他子项。示例:
<LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="200dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toplayout">
<com.android.volley.toolbox.NetworkImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:background="@android:color/transparent"
android:id="@+id/imageitem"/>
</LinearLayout>