2016-07-27 4 views
2

Я пытаюсь создать приложение для фотоколлажа. Здесь я динамически добавляю изображения в относительный макет, передавая массив позиций для создания сетки. Сетки успешно созданы. Но когда я добавляю изображения, изображения не масштабируются должным образом или не подходят для всей области изображения. Кроме того, когда я добавляю касание слушателя картинки, изображения moviing вне зоны imageview.Please помочь мне в this.Thanks заранее Вот мой кодИзображения не изменяются при динамическом добавлении изображений в относительном макете

public void drawGrids() { 
    Resources res = getResources(); 
    int Rid = c.id; 

    TypedArray ta = res.obtainTypedArray(Rid); 
    int n = ta.length(); 
    String[][] array = new String[n][]; 
    for (int i = 0; i < n; ++i) { 
     int id = ta.getResourceId(i, 0); 
     if (id > 0) { 
      array[i] = res.getStringArray(id); 
      Log.e(" array", "" + i + " " + Arrays.toString(array[i])); 
      String[] values = Arrays.toString(array[i]).replaceAll("[\\[\\]\\s]", "").split(","); // extracting each element from array 

      final int position = i; 

      limit = position+1; 
      float x = Float.parseFloat(values[0]); 
      float y = Float.parseFloat(values[1]); 
      float w = Float.parseFloat(values[2]); 
      float h = Float.parseFloat(values[3]); 
      Log.e(" x:", "" + x); 
      Log.e(" y:", "" + y); 
      Log.e(" w:", "" + w); 
      Log.e(" h:", "" + h); 

      img1 = new ImageView(getActivity()); 

      img1.setImageResource(R.drawable.button_background);   

      params = new RelativeLayout.LayoutParams((int) ((Screen_width * w) - padding), (int) ((Screen_height * h) - padding)); 

      // x= x* Screen_width 
      // y= y* Screen_height 
      params.leftMargin = (int) ((Screen_width * x) + padding); 
      params.topMargin = (int) ((Screen_height * y) + padding); 
      params.rightMargin = padding; 
      params.bottomMargin = padding; 
      Log.e(" px(x):", "" + (int) (Screen_width * x)); 
      Log.e(" px(y):", "" + (int) (Screen_height * y)); 
      Log.e(" px(w):", "" + (int) (Screen_width * w)); 
      Log.e("px(h)", "" + (int) (Screen_height * h)); 

      if(!mSelectedImages.isEmpty()) { 
       onPickedSuccessfully(mSelectedImages); 
      } 
      else { 
       img1.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         Log.e("clicked", "" + position); 
         onClickPickImageMultipleWithLimit(img1); 
        } 
       }); 
      } 

     IMGS.add(img1); // arraylist of imageview 
      root1.addView(img1, params); 
      createPreview(); 
     } else { 
      // something wrong with the XML 
     } 
    } 

    ta.recycle(); 


} 

public void onPickedSuccessfully(ArrayList<ImageEntry> images) { //  selected images path are to be fetched here 
     mSelectedImages = images; 


     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       for (j = 0; j <IMGS.size(); j++) { 

        final ImageView child=IMGS.get(j); 

        child.onTouchListener(new MultiTouchListener);// multitouch listener for zooming and scrolling picked image 
        Log.e("w n h", "" + child.getWidth() + " " + child.getHeight()); 

        int areaheight = child.getWidth(); 
        int areawidth = child.getHeight(); 

        BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
        oldBitmap = BitmapFactory.decodeFile(String.valueOf(mSelectedImages.get(j)), bmOptions);//decodeFile(String.valueOf(mSelectedImages.get(j))); 

        int height = oldBitmap.getHeight(), width = oldBitmap.getWidth(); 
        Log.e(" b width and height ", "" + oldBitmap.getWidth() + " " + oldBitmap.getHeight()); 
        Log.e(" area width and height ", "" + areawidth + " " + areaheight); 

        Bitmap scaledBitmap; 
        if (areaheight > areawidth) { 
         // portrait 
         float ratio = (float) height/areaheight; 
         height = areaheight; 
         width = (int) (width/ratio); 
         scaledBitmap = Bitmap.createScaledBitmap(oldBitmap, width, height, true); 
         Log.e("porait scaled w ht ", "" + scaledBitmap.getWidth() + " " + scaledBitmap.getHeight()); 

        } else if (areawidth > areaheight) { 
         //landscape 
         float ratio = (float) width/areawidth; 
         width = areawidth; 
         height = (int) (height/ratio); 
         scaledBitmap = Bitmap.createScaledBitmap(oldBitmap, width, height, true); 
         Log.e("landscape scaled w ht ", "" + scaledBitmap.getWidth() + " " + scaledBitmap.getHeight()); 
        } else { 
         // square 
         height = areaheight; 
         width = areawidth; 
         scaledBitmap = Bitmap.createScaledBitmap(oldBitmap, width, height, true); 
         Log.e("square scaled w ht ", "" + scaledBitmap.getWidth() + " " + scaledBitmap.getHeight()); 

        } 
        child.setImageBitmap(scaledBitmap); 
       } 
      } 
     }); 
+0

Извините за вопрос, но почему вы не хотите, чтобы пользователь RecyclerView с GridLayoutManager работал с сеткой изображений, он сохранит вашу память? –

+0

Потому что у меня есть сетки изображений. когда я выбираю любое изображение, я хочу рисовать сетки в соответствии с этим, поэтому для этого я сохранил позиции в массиве. И я не уверен, как это сделать с просмотром Recycler, где я могу просто дать spansize – user65

ответ

1

В вашем случае вам нужно добавить строку:

img1.setScaleType(ImageView.ScaleType.CENTER_CROP); // or CENTER_INSIDE, or FIT_CENTER, or for example FIT_XY 

после:

img1.setImageResource(R.drawable.button_background); 

Таким образом, вы обеспечите масштабирование для всех изображений, которые будут установлены в вашем ImageView. Вы можете узнать больше о scaleType here и here

+0

спасибо, если я установлю centerCrop, он отрежет другие части изображения. Я хочу отобразить часть изображения, а затем прокрутить изображение, чтобы показать другую часть. – user65

+0

Если вы перейдете ко второй ссылке, вы найдете, например, тип шкалы MATRIX, который масштабирует ваше изображение на весь экран, но будет отображаться в изображенииView только часть, поэтому вы сможете, например, перетащить ее (изображение) и увидеть другие части изображения. –

+0

Кроме того, как я знаю, вы можете указать матрицу через 'void setImageMatrix (матричная матрица)' –

1

Вместо использования ImageView и setOnTouchListener вы можете попробовать это пользовательское представление.

public class ScaleImageView extends ImageView { 

private ScaleGestureDetector mScaleDetector; 
private float mScaleFactor = 1.0f; 
private float x = 0; 
private float y = 0; 
private float tx = 0; 
private float ty = 0; 
private float dx = 0; 
private float dy = 0; 
private int scrollLimitX = 0; 
private int scrollLimitY = 0; 
private boolean justScaled = false; 

public ScaleImageView(Context context) { 
    super(context); 
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
} 

public ScaleImageView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
} 

@SuppressLint("ClickableViewAccessibility") 
@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    if(ev.getPointerCount() == 1){ 
     switch(ev.getAction()){ 
     case MotionEvent.ACTION_DOWN: 
      tx = ev.getX(); 
      ty = ev.getY(); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      if(!justScaled){ 
       dx = tx - ev.getX(); 
       dy = ty - ev.getY(); 
       tx -= dx; 
       ty -= dy; 
       int scrollX = (int)(this.getScrollX()/mScaleFactor); 
       int scrollY = (int)(this.getScrollY()/mScaleFactor); 
       if(Math.abs(scrollX+dx) > scrollLimitX) dx = 0; 
       if(Math.abs(scrollY+dy) > scrollLimitY) dy = 0; 
       this.scrollBy((int)(dx*mScaleFactor), (int)(dy*mScaleFactor)); 
      } 
      break; 
     case MotionEvent.ACTION_UP: 
      justScaled = false; 
      break; 
     } 
    }else if(ev.getPointerCount() == 2){ 
     justScaled = true; 
     mScaleDetector.onTouchEvent(ev); 
    } 
    return super.onTouchEvent(ev); 
} 

@Override 
public void onDraw(Canvas canvas) { 
    x = this.getWidth()/2; 
    y = this.getHeight()/2; 
    canvas.scale(mScaleFactor, mScaleFactor, x ,y); 
    int scrollX = (int)(this.getScrollX()/mScaleFactor); 
    int scrollY = (int)(this.getScrollY()/mScaleFactor); 
    if(Math.abs(scrollX) > scrollLimitX) dx = scrollLimitX - scrollX; else dx = 0; 
    if(Math.abs(scrollY) > scrollLimitY) dy = scrollLimitY - scrollY; else dy = 0; 
    this.scrollBy((int)(dx*mScaleFactor), (int)(dy*mScaleFactor)); 
    super.onDraw(canvas); 
} 

public void setScaleFactor(float mfactor){ 
    this.mScaleFactor = mfactor; 
} 

public float getScaleFactor(){ 
    return this.mScaleFactor; 
} 

public void setScrollLimit(int x, int y){ 
    this.scrollLimitX = x/2; 
    this.scrollLimitY = y/2; 
} 

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
     mScaleFactor *= detector.getScaleFactor(); 
     mScaleFactor = Math.max(1.0f, Math.min(mScaleFactor, 5.0f)); 
     ScaleImageView.this.invalidate(); 
     return true; 
    } 
} 

} 

Чтобы ограничить изображение, по меньшей мере, один угол внутри вида:

// zoomImg is the Bitmap. 
// mZoomImage is the ScaleImageView. 
float scaleFactor = Math.min((float)(mZoomImage.getWidth())/zoomImg.getWidth(), (float)(mZoomImage.getHeight())/zoomImg.getHeight()); 
mZoomImage.setScrollLimit((int)(zoomImg.getWidth()*scaleFactor), (int)(zoomImg.getHeight()*scaleFactor)); 

Надежда это полезно!

+0

Я попробовал ваше решение, и изображения получаются масштабированными за пределами вида. – user65

+0

К вышеуказанному коду вам нужно узнать foucs (x, y) внутри ScaleGestureDector и изменить (x, y) в onDraw (). Может быть, вы можете искать «изображение с увеличенным изображением» в Github.com, которое даст вам некоторые другие варианты. –

 Смежные вопросы

  • Нет связанных вопросов^_^