2012-02-01 9 views
15

Что я пытаюсь реализовать?Галерея изображений с использованием ViewPager + увеличение в ImageViews

A галерея изображений с использованием ViewPager. Я выбираю этот вариант, потому что плавный переход между изображениями (я использую ImageView), это хорошо и довольно легко реализовать.

В чем моя проблема?

Я смог реализовать все это , но зум не работает. Я могу видеть в LogCat как он напечатан ZOOM (код находится в конце сообщения), но изображение не увеличено. Всего несколько замечаний по поводу следующего кода:

  • ImageViewHelperURL.setUrlDrawable((ImageView) img, url, R.drawable.no_image); Я использую UrlImageViewHelper для загрузки асинхронно изображений из Интернета.
  • api.getListUrls() Это ArrayList, где у меня есть URL-адреса изображений.
  • Я пробовал также с помощью ImageView из R.drawable вместо загрузки изображения

    import android.content.Context; 
    import android.content.Intent; 
    import android.graphics.Matrix; 
    import android.graphics.PointF; 
    import android.os.Bundle; 
    import android.support.v4.app.ActionBar; 
    import android.support.v4.app.Fragment; 
    import android.support.v4.app.FragmentActivity; 
    import android.support.v4.app.FragmentManager; 
    import android.support.v4.app.FragmentPagerAdapter; 
    import android.support.v4.view.Menu; 
    import android.support.v4.view.MenuItem; 
    import android.support.v4.view.ViewPager; 
    import android.util.FloatMath; 
    import android.util.Log; 
    import android.view.LayoutInflater; 
    import android.view.MenuInflater; 
    import android.view.MotionEvent; 
    import android.view.View; 
    import android.view.View.OnTouchListener; 
    import android.view.ViewGroup; 
    import android.view.ViewGroup.LayoutParams; 
    import android.widget.Gallery; 
    import android.widget.ImageView; 
    import android.widget.Toast; 
    
    public class Slide extends FragmentActivity { 
        private ViewPager mPager; 
        public static Api api; 
        public static int POSITION; 
        public static ActionBar topbar; 
        public static Context ctx; 
    
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         setContentView(R.layout.fragment); 
         ctx = Slide.this; 
         POSITION = 0; 
         topbar = getSupportActionBar(); 
    
         /* get portadas */ 
         api = new Api(); 
         api.getUrlsFromAPI(); 
    
         topbar.setDisplayShowHomeEnabled(false); 
         topbar.setDisplayShowTitleEnabled(true); 
    
         mPager = (ViewPager) findViewById(R.id.pager); 
         mPager.setAdapter(new TestAdapter(getSupportFragmentManager())); 
        } 
    
        @Override 
        protected void onResume() { 
         // TODO Auto-generated method stub 
         super.onResume(); 
         mPager.setCurrentItem(POSITION); 
        } 
    
        static final class TestAdapter extends FragmentPagerAdapter { 
         public TestAdapter(FragmentManager fm) { 
          super(fm); 
         } 
    
         @Override 
         public int getCount() { 
          return api.getListUrls().size(); 
         } 
    
         @Override 
         public Fragment getItem(int position) { 
          TestFragment f = new TestFragment(); 
    
          f.url = api.getListUrls().get(position).getUrl(); 
          f.position = position; 
          return f; 
         } 
        } 
    
        public static class TestFragment extends Fragment { 
         String url = ""; 
         Integer position = 0; 
    
         public TestFragment() { 
          setRetainInstance(true); 
         } 
    
         @Override 
         public void onCreate(Bundle savedInstanceState) { 
          super.onCreate(savedInstanceState); 
          setHasOptionsMenu(true); 
         } 
    
         @Override 
         public View onCreateView(LayoutInflater inflater, ViewGroup container, 
           Bundle savedInstanceState) { 
          ImageView img = new ImageView(getActivity()); 
    
          img.setPadding(6, 6, 6, 6) ; 
          img.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)) ; 
    
          ImageViewHelperURL.setUrlDrawable((ImageView) img, url, R.drawable.no_image) ; 
    
          img.setOnTouchListener(new OnTouchListener() { 
           private static final String TAG = "SlideImageView"; 
           // These matrices will be used to move and zoom image 
           Matrix matrix = new Matrix(); 
           Matrix savedMatrix = new Matrix(); 
    
           // We can be in one of these 3 states 
           static final int NONE = 0; 
           static final int DRAG = 1; 
           static final int ZOOM = 2; 
           int mode = NONE; 
    
           // Remember some things for zooming 
           PointF start = new PointF(); 
           PointF mid = new PointF(); 
           float oldDist = 1f; 
    
           @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(event.getX(), event.getY()); 
             Log.d(TAG, "mode=DRAG"); 
             mode = DRAG; 
             break; 
            case MotionEvent.ACTION_POINTER_DOWN: 
             oldDist = spacing(event); 
             Log.d(TAG, "oldDist=" + oldDist); 
             if (oldDist > 10f) { 
              savedMatrix.set(matrix); 
              midPoint(mid, event); 
              mode = ZOOM; 
              Log.d(TAG, "mode=ZOOM"); 
             } 
             break; 
            case MotionEvent.ACTION_UP: 
            case MotionEvent.ACTION_POINTER_UP: 
             mode = NONE; 
             Log.d(TAG, "mode=NONE"); 
             break; 
            case MotionEvent.ACTION_MOVE: 
             if (mode == DRAG) { 
              // ... 
              matrix.set(savedMatrix); 
              matrix.postTranslate(event.getX() - start.x, 
                event.getY() - start.y); 
             } else if (mode == ZOOM) { 
              float newDist = spacing(event); 
              Log.d(TAG, "newDist=" + newDist); 
              if (newDist > 10f) { 
               matrix.set(savedMatrix); 
               float scale = newDist/oldDist; 
               Log.d(TAG, "ZOOOOOOOM: " + scale); 
               matrix.postScale(scale, scale, mid.x, mid.y); 
              } 
             } 
             break; 
            } 
    
            view.setImageMatrix(matrix); 
            return true; // indicate event was handled 
           } 
    
           /** Show an event in the LogCat view, for debugging */ 
           private void dumpEvent(MotionEvent event) { 
            String names[] = { "DOWN", "UP", "MOVE", "CANCEL", 
              "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", 
              "8?", "9?" }; 
            StringBuilder sb = new StringBuilder(); 
            int action = event.getAction(); 
            int actionCode = action & MotionEvent.ACTION_MASK; 
            sb.append("event ACTION_").append(names[actionCode]); 
            if (actionCode == MotionEvent.ACTION_POINTER_DOWN 
              || actionCode == MotionEvent.ACTION_POINTER_UP) { 
             sb.append("(pid ").append(
               action >> MotionEvent.ACTION_POINTER_ID_SHIFT); 
             sb.append(")"); 
            } 
            sb.append("["); 
            for (int i = 0; i < event.getPointerCount(); i++) { 
             sb.append("#").append(i); 
             sb.append("(pid ").append(event.getPointerId(i)); 
             sb.append(")=").append((int) event.getX(i)); 
             sb.append(",").append((int) event.getY(i)); 
             if (i + 1 < event.getPointerCount()) 
              sb.append(";"); 
            } 
            sb.append("]"); 
            Log.d(TAG, sb.toString()); 
           } 
    
           /** Determine the space between the first two fingers */ 
           private float spacing(MotionEvent event) { 
            float x = event.getX(0) - event.getX(1); 
            float y = event.getY(0) - event.getY(1); 
            return FloatMath.sqrt(x * x + y * y); 
           } 
    
           /** Calculate the mid point of the first two fingers */ 
           private void midPoint(PointF point, MotionEvent event) { 
            float x = event.getX(0) + event.getX(1); 
            float y = event.getY(0) + event.getY(1); 
            point.set(x/2, y/2); 
           } 
          }); 
    
          return img; 
         } 
    
         @Override 
         public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    
         } 
    
         @Override 
         public boolean onOptionsItemSelected(MenuItem item) { 
    
          return super.onOptionsItemSelected(item); 
         } 
        } 
    
    } 
    

Я уже пробовал следующий урок без успеха:

+0

Поздно к этому вопросу - но если вы используете ViewPager для своей галереи, вы никогда не перерабатываете все эти фрагменты, верно? Вы просто продолжаете создавать новые? – user291701

+0

Я думаю, что я их перерабатываю. Когда вы вернетесь (к предыдущей деятельности), этот уничтожен? Но я просто начинающий в этом, я не уверен. –

ответ

9

Если вы хотите использовать матрицу с ImageView для преобразования t ему нужно изменить scale type на ScaleType.Matrix, иначе эффект не будет. Тип шкалы по умолчанию - ScaleType.FIT_CENTER, поэтому он игнорирует матрицу.

Что касается вашей первоначальной задачи, если вы получаете эту работу, вы можете обнаружить, что сенсорные жесты на ImageView будут мешать прокрутке ViewPager. У вас наверняка возникнут проблемы с поддержкой перетаскивания одним касанием, потому что это напрямую соответствует естественному движению прокрутки ViewPager, чтобы перейти к следующему виду.

+0

Да, вы правы в отношении помех ... Однако теперь я могу увеличить изображение :) Знаете ли вы, что лучший способ реализовать галерею изображений? Конечно, поддержка масштабирования. –

+0

Я сделал это точно так же. Для помех я попытался отключить жестов flv ViewPager. Это отлично поработало, но я не получил ошибку индекса из диапазона без причины? Но причиной был мой переопределенный ViewPager, я думаю, что есть ошибка в пакете совместимости v4. Но я не нашел способ jat отключить бросок и просто увеличить. Если я сниму первый указатель, мое приложение выйдет из строя :( – Informatic0re