2012-02-01 11 views
15

Che cosa sto cercando di implementare?Galleria di immagini usando ViewPager + zoom in ImageViews

A galleria di immagini con ViewPager. Scelgo questa opzione perché la transizione graduale tra le immagini (sto usando ImageView), è piacevole e abbastanza facile da implementare.

Qual è il mio problema esattamente?

Sono stato in grado di implementare tutto questo ma lo zoom non funziona. Vedo in LogCat come viene stampato ZOOM (il codice si trova alla fine del post) ma l'immagine non è ingrandita. A pochi note circa il seguente codice:

  • ImageViewHelperURL.setUrlDrawable((ImageView) img, url, R.drawable.no_image); che sto usando UrlImageViewHelper per scaricare in modo asincrono le immagini dal web.
  • api.getListUrls() È un arraylist in cui sono presenti gli URL delle immagini.
  • ho provato anche con un ImageView da R.drawable invece di scaricare l'immagine

    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); 
         } 
        } 
    
    } 
    

Ho già provato il seguente tutorial senza successo:

+0

In ritardo a questa domanda - ma se stai usando un ViewPager per la tua galleria - non riciclerai mai tutti quei frammenti, giusto? Continui a crearne di nuovi? – user291701

+0

Penso che li sto riciclando. Quando torni indietro (all'attività precedente), questo viene distrutto? Ma sono solo un principiante in questo, non ne sono sicuro. –

risposta

9

Se si desidera utilizzare una matrice con un ImageView per trasformare t lui immagine, è necessario modificare il scale type a ScaleType.Matrix, altrimenti non ci sarà alcun effetto. Il tipo di scala predefinito è ScaleType.FIT_CENTER e pertanto ignorerà la matrice.

Per quanto riguarda l'attività originale, se si ottiene questo funzionamento si può scoprire che i gesti touch sul ImageView interferirà con lo scorrimento del ViewPager. Avrai sicuramente problemi nel supportare il trascinamento a tocco singolo perché questo corrisponde direttamente al movimento di scorrimento naturale di ViewPager per passare alla vista successiva.

+0

Sì, hai ragione sull'interferenza ... Tuttavia, ora sono in grado di ingrandire l'immagine :) Conosci un modo migliore per implementare una galleria di immagini? Zoom di supporto, ovviamente. –

+0

L'ho fatto nello stesso modo. Per l'interferenza ho provato a disabilitare il gesto di lancio del ViewPager. Ha funzionato benissimo, ma ho ottenuto un errore di indice fuori intervallo senza motivo? Ma il motivo era il mio ViewPager sovrascritto, penso che ci sia un bug nel pacchetto di compatibilità v4. Ma non ho trovato un modo per disabilitare l'avventura e solo lo zoom. Se sollevo il primo puntatore, la mia app si blocca :( – Informatic0re

Problemi correlati