2017-02-18 4 views
8

Я пытаюсь использовать некоторые простые манипуляции с фотографиями на изображении в верхней части activity в пределах ImageView, который в среднем имеет высоту 200dp и соответствует ширине ее родительского элемента.Android - проблемы с перетаскиванием и обрезкой

я реализовал пользовательский класс onTouchListener, который создает matrix и переводит изображение в ImageView

Drag:

case MotionEvent.ACTION_MOVE: 
    if (mode == DRAG) { 
     matrix.set(savedMatrix); 
     matrix.postTranslate(v.getX(), event.getY() - start.y); 
    } 
    break; 

Это отлично работает, он тащит изображение на у ось только. Но когда пользователь выпускает, я хочу, чтобы изображение обрезалось до границ видимой области ImageView.

Crop:

case MotionEvent.ACTION_UP: 
    if (mode == DRAG) { 
     Bitmap bitmap = drawableToBitmap(view.getDrawable()); 
     Bitmap result = Bitmap.createBitmap(bitmap,view.getLeft(), view.getTop(), view.getWidth(), view.getHeight()); 
     view.setImageBitmap(result); 
     } 
     break; 

Это обрезает изображение до нужного размера, но только из верхней части фоне не ImageView видимых границ. При вызове функции класса BitmapcreateBitmap(int x, int y, int width, int height) мое единственное предположение: view.getTop() запускает его сверху.

Итак, мой вопрос: как я мог рассчитать разницу между вершиной видимых границ обзора и границами фона/матрицы?

The dark blue area is the ImageView

Примечание: Изображение отображает изображение (синий), который расположен в верхней части активности (голубой ищет области являются только фоном невидимые границы ImageView, не активности)

Я хотел бы подчеркнуть, что я не хочу использовать сторонние библиотеки для достижения этой цели.

Я более чем готов предоставить дополнительный код, если потребуется.

Update:

Полный onTouch метод:

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    ImageView view = (ImageView) v; 
    // Dump touch event to log 
    dumpEvent(event); 

    // Handle touch events here... 
    switch (event.getAction() & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: 
      savedMatrix.set(matrix); 
      start.set(v.getX(), event.getY()); 
      mode = DRAG; 
      originalY.y = (int) event.getY(); 
      break; 
     case MotionEvent.ACTION_UP: 
      if (mode == DRAG) { 
     Bitmap bitmap = drawableToBitmap(view.getDrawable()); 
     Bitmap result = Bitmap.createBitmap(bitmap,view.getLeft(), view.getTop(), view.getWidth(), view.getHeight()); 
     view.setImageBitmap(result); 
     } 
     break; 
     case MotionEvent.ACTION_POINTER_UP: 
      mode = NONE; 
      break; 
     case MotionEvent.ACTION_MOVE: 
      if (mode == DRAG) { 
       matrix.set(savedMatrix); 
       matrix.postTranslate(v.getX(), event.getY() - start.y); 
      } 
      break; 
    } 
    view.setImageMatrix(matrix); 
    return true; // indicate event was handled 
} 
+0

на вашем экране Выстрел, любое растровое изображение, которое вы устанавливаете в фоновом режиме на весь экран, или вы устанавливаете любую высоту, я знаю, что вы положили 200dp, но я думаю, что его видимая область изображения должна быть обрезана при нажатии кнопки, поэтому, если вы предоставите мне отображают информацию на экране с фактическим изображением, после чего я бы вызывающе помог вам. –

+0

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

ответ

0

Для вычисления высоты корневой активности, мы можем использовать

int height = this.getWindow().getDecorView().getHeight(); 

или вы можете использовать показатели дисплея, как

DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 
int width = metrics.widthPixels; 
int height = metrics.heightPixels; 

Или добавить глобальный макет слушателя

ViewTreeObserver vtObserver = view.getViewTreeObserver(); 
vtObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
@Override 
public void onGlobalLayout() { 
    // check if the view's height and/or width > 0 
    // don't forget to remove the listener when done using removeOnGlobalLayoutListener 
} 

});

+0

Пожалуйста, перечитайте вопрос. Я ищу границы между видимой областью ImageView (синий) (и значением границ верхней части этой видимой области в верхней части границ фона/матрицы (голубой)). Внутри Activity Image будет много виджетов, поэтому получение высоты активности будет излишним. –

0

код не хватает какой-то контекст, но я предполагаю, что, когда пользователь начинает перетаскивать создавать новый savedMatrix и start точку и обновлять их каждый раз onTouchListener называется или иначе я не понимаю, как ваш код работает на всех.

Если это так, то у вас действительно есть перевод, который вам нужен в savedMatrix, так почему бы не понять это правильно? Я думаю, что вам нужно что-то вроде

int top = savedMatrix.getValues()[Matrix.MTRANS_Y] 

я не проверил его и не знаю внутреннюю структуру Matrix достаточно хорошо, так что вам может понадобиться, чтобы инвертировать знак top.

Sidenote: Непонятно, почему в matrix.postTranslate(v.getX(), event.getY() - start.y); вы проходите v.getX(). Вероятно, он работает нормально только потому, что v.getX() всегда 0 в вашем сценарии.

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