Domanda

I'm using this CoverFlow : http://www.inter-fuser.com/2010/02/android-coverflow-widget-v2.html

I want to for the coverflow to adapt to the different screen sizes,

I have modded the coverflow slightly so that I use an XML layout instead.

Here's how the layout should and looks like on my Phone (320x480)

GOOD

Here's how the layout looks like on a Nexus One (480x720 in emulator) BAD

COVERFLOW CLASS :

public class CoverFlow extends Gallery {

    /**
     * Graphics Camera used for transforming the matrix of ImageViews
     */
    private final Camera mCamera = new Camera();

    /**
     * The maximum angle the Child ImageView will be rotated by
     */    
    private int mMaxRotationAngle = 80;

    /**
     * The maximum zoom on the centre Child
     */
    // TODO RENDRE LA VALEUR DYNAMIQUE SUR LA TAILLE DE L'ECRAN

//    private int mMaxZoom = -430;
    private int mMaxZoom = -370;

    /**
     * The Centre of the Coverflow 
     */   
    private int mCoveflowCenter;

 public CoverFlow(Context context) {
  super(context);
  this.setStaticTransformationsEnabled(true);
 }

 public CoverFlow(Context context, AttributeSet attrs) {
  super(context, attrs);
        this.setStaticTransformationsEnabled(true);
 }

  public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
   super(context, attrs, defStyle);
   this.setStaticTransformationsEnabled(true);   
  }

    /**
     * Get the max rotational angle of the image
  * @return the mMaxRotationAngle
  */
 public int getMaxRotationAngle() {
  return mMaxRotationAngle;
 }

 /**
  * Set the max rotational angle of each image
  * @param maxRotationAngle the mMaxRotationAngle to set
  */
 public void setMaxRotationAngle(int maxRotationAngle) {
  mMaxRotationAngle = maxRotationAngle;
 }

 /**
  * Get the Max zoom of the centre image
  * @return the mMaxZoom
  */
 public int getMaxZoom() {
  return mMaxZoom;
 }

 /**
  * Set the max zoom of the centre image
  * @param maxZoom the mMaxZoom to set
  */
 public void setMaxZoom(int maxZoom) {
  mMaxZoom = maxZoom;
 }

 /**
     * Get the Centre of the Coverflow
     * @return The centre of this Coverflow.
     */
    private int getCenterOfCoverflow() {
        return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();
    }

    /**
     * Get the Centre of the View
     * @return The centre of the given view.
     */
    private static int getCenterOfView(View view) {
        return view.getLeft() + view.getWidth() / 2;
    }  
    /**
  * {@inheritDoc}
  *
  * @see #setStaticTransformationsEnabled(boolean) 
  */ 
    @Override
    protected boolean getChildStaticTransformation(View child, Transformation t) {

  final int childCenter = getCenterOfView(child);
  final int childWidth = child.getWidth() ;
  int rotationAngle = 0;

  t.clear();
  t.setTransformationType(Transformation.TYPE_MATRIX);

        if (childCenter == mCoveflowCenter) {
            transformImageBitmap((ImageView) child, t, 0);
        } else {      
            rotationAngle = (int) (((float) (mCoveflowCenter - childCenter)/ childWidth) *  mMaxRotationAngle);
            if (Math.abs(rotationAngle) > mMaxRotationAngle) {
             rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;   
            }
            transformImageBitmap((ImageView) child, t, rotationAngle);         
        }    

  return true;
 }

 /**
  * This is called during layout when the size of this view has changed. If
  * you were just added to the view hierarchy, you're called with the old
  * values of 0.
  *
  * @param w Current width of this view.
  * @param h Current height of this view.
  * @param oldw Old width of this view.
  * @param oldh Old height of this view.
     */
     @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
      mCoveflowCenter = getCenterOfCoverflow();
      super.onSizeChanged(w, h, oldw, oldh);
     }

     /**
      * Transform the Image Bitmap by the Angle passed 
      * 
      * @param imageView ImageView the ImageView whose bitmap we want to rotate
      * @param t transformation 
      * @param rotationAngle the Angle by which to rotate the Bitmap
      */
     private void transformImageBitmap(ImageView child, Transformation t, int rotationAngle) {            
      mCamera.save();
      final Matrix imageMatrix = t.getMatrix();;
      final int imageHeight = child.getLayoutParams().height;;
      final int imageWidth = child.getLayoutParams().width;
      final int rotation = Math.abs(rotationAngle);

      mCamera.translate(0.0f, 0.0f, 100.0f);

      //As the angle of the view gets less, zoom in     
      if ( rotation < mMaxRotationAngle ) {
       float zoomAmount = (mMaxZoom + rotation);
       mCamera.translate(0.0f, 0.0f, zoomAmount);          
      } 

      mCamera.rotateY(rotationAngle);
      mCamera.getMatrix(imageMatrix);               
      imageMatrix.preTranslate(-(imageWidth/2), -(imageHeight/2)); 
      imageMatrix.postTranslate((imageWidth/2), (imageHeight/2));
      mCamera.restore();
 }
}

HOME ACTIVITY :

public class HomeActivity extends Activity {

    private  final static String TAG = "HomeActivity";
    private TextView pageNameTextView;
    private CoverFlow coverFlow;
    private ImageAdapter coverImageAdapter;
    private int itemSelected = 0;
    private Context context;
    private SparseArray<String> listeNomIcons;
    private int currentImagePosition = 0;

    //Info button
    private ImageView infoAccueilImageView; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_layout);
        //animate Transition
        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);

        context = this;

        listeNomIcons = new SparseArray<String>();
        listeNomIcons.put(0, "DELAIS D'ATTENTE, RETARD");
        listeNomIcons.put(1, "COURRIER SUBSTITUTION");
        listeNomIcons.put(2, "IR LC");
        listeNomIcons.put(3, "CONTACTS UTILES");
        listeNomIcons.put(4, "TEMPS DE PAUSE");
        listeNomIcons.put(5, "DISPERTION");
        listeNomIcons.put(6, "PRORATA REPOS");
        listeNomIcons.put(7, "ALERTE DOMICILE");
        listeNomIcons.put(8, "RESERVE DOMICILE");
        listeNomIcons.put(9, "RADD");
        listeNomIcons.put(10, "JOKER");

        coverFlow = (CoverFlow)findViewById(R.id.coverflow);  
        coverImageAdapter =  new ImageAdapter(this);  
        coverFlow.setAdapter(coverImageAdapter);
        coverFlow.setSelection(0, true);
        coverFlow.setAnimationDuration(1000);

        //cover

        pageNameTextView = (TextView)findViewById(R.id.page_nameTextView);

        //Info Accueil Image View
        infoAccueilImageView = (ImageView)findViewById(R.id.infoImageView);
        infoAccueilImageView.setOnClickListener( new OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(context, InfoAccueilActivity.class));
            }
        } ) ;

        coverFlow.setOnItemSelectedListener(new OnItemSelectedListener(){
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                currentImagePosition = position; //this will update your current marker
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        });

        Button goLeft = (Button) findViewById(R.id.select_leftButton);
        goLeft.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // go to previous image

                coverFlow.onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(0, 0));
            }
        });

        Button goRight = (Button) findViewById(R.id.select_rightButton);
        goRight.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // go to next item
                coverFlow.onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, new KeyEvent(0, 0));
            }
        });

        coverFlow.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {

                if(itemSelected == arg2)
                {
                    Log.d(TAG, "arg2 : "+arg2);
                    switch (arg2) {
                    case 0:
                        startActivity(new Intent(context, DelaisAttenteActivity.class));
                        break;
                    case 1:
                        startActivity(new Intent(context, CourrierSubstitutionActivity.class));
                        break;
                    case 2:
                        startActivity(new Intent(context, IRLCActivity.class));
                        break;
                    case 3:
                        startActivity(new Intent(context, ContactsActivity.class));
                        break;
                    case 4:
                        startActivity(new Intent(context, TempsPauseActivity.class));
                        break;
                    case 5:
                        startActivity(new Intent(context, DispertionActivity.class));
                        break;
                    case 6:
                        startActivity(new Intent(context, ProrataReposActivity.class));
                        break;
                    case 7:
                        startActivity(new Intent(context, AlerteDomicileActivity.class));
                        break;
                    case 8:
                        startActivity(new Intent(context, ReserveDomicileActivity.class));
                        break;                      
                    case 9:
                        startActivity(new Intent(context, ReposAdditionnelActivity.class));
                        break;
                    case 10:
                        startActivity(new Intent(context, JokerActivity.class));
                        break;

                    default:
                        break;
                    }
                }
            }
        });
        coverFlow.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {

                pageNameTextView.setText(listeNomIcons.get(arg2));
                itemSelected = arg2;
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        });
    }

    public class ImageAdapter extends BaseAdapter {
        int mGalleryItemBackground;
        private final Context mContext;


        private final Integer[] mImageIds = {
                R.drawable.retard_controller,
                R.drawable.courrier_substitution_controller,
                R.drawable.irmf_controller,
                R.drawable.contacts_controller,
                R.drawable.pause_controller,
                R.drawable.dispersion_controller,
                R.drawable.repos_controller,
                R.drawable.alerte_controller,
                R.drawable.reserve_domicile_controller,
                R.drawable.repos_additionnel_controller,
                R.drawable.joker_controller
        };

        private final ImageView[] mImages;

        public ImageAdapter(Context c) {
            mContext = c;
            mImages = new ImageView[mImageIds.length];
        }

        @Override
        public int getCount() {
            return mImageIds.length;
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            //Use this code if you want to load from resources
            ImageView i = new ImageView(mContext);
            i.setImageResource(mImageIds[position]);
            i.setLayoutParams(new CoverFlow.LayoutParams(130, 130));
            i.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 
            //Make sure we set anti-aliasing otherwise we get jaggies
            BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
            drawable.setAntiAlias(true);
            return i;

            //return mImages[position];
        }
        /** Returns the size (0.0f to 1.0f) of the views 
         * depending on the 'offset' to the center. */ 
        public float getScale(boolean focused, int offset) { 
            /* Formula: 1 / (2 ^ offset) */ 
            return Math.max(0, 1.0f / (float)Math.pow(2, Math.abs(offset))); 
        } 

    }
}
È stato utile?

Soluzione

I found a way around, not a great solution but it works pretty well on the devices that I have tested it on...

In the method (in the ImageAdapter in HomeActivity)

@Override
public View getView(int position, View convertView, ViewGroup parent)

there I change the size of the image on this line

i.setLayoutParams(new CoverFlow.LayoutParams(130, 130));

to

int imageSize = calculateSize();
i.setLayoutParams(new CoverFlow.LayoutParams(imageSize, imageSize));

I set imageSize in my onCreate with this method

public int calculateSize()
{
    // GET SCREEN SIZE
    Display display = getWindowManager().getDefaultDisplay();

    // HEIGHT
    int height = display.getHeight();
    long roundedHeightSize = Math.round((0.2132*height)+27.177);

    //WIDTH
    int width = display.getWidth();
    long roundedWidthSize = Math.round((0.4264*width)-6.9355);


    return (int)((roundedHeightSize+roundedWidthSize)/2);
}

TO GET THE FUNCTION :

(0.2132*height)+27.177 & (0.4264*width)-6.9355

I tested manually the height of the image needed on the different devices I had available

Galaxy SIII : 300 (1280x720)

Xperia Mini Pro : 135 (480x320)

Xperia X10 Mini Pro : 95 (320x240)

f(1280)=300
f(480)=135
f(320)=95

f(x) = 0.2132X + 27.177

then I did the same as the width..

I then get the average of the height and width given from these two functions to get the best value for the height and width of the image (seeing as the image is square => width = height)

Altri suggerimenti

there is a alphaSpacing kind of int variable, just increase its value . however i can not not remember exact class and variable name as its almost 2 years, when i used this code . but yes, one thing i remember is that i came across very same issue and i had absolutely no idea about stackoverflow. so was trying with different values and eventually succeeded .

I suggested to use values from dimens.xml. As example in the getView method in the adapter:

if (convertView == null) {
            convertView = lInflater.inflate(R.layout.item_gallery, null);
            ((RelativeLayout) convertView.findViewById(R.id.image_issue_layout)).setLayoutParams(new CoverFlowView.LayoutParams(
                    app.getResources().getDimensionPixelSize(R.dimen.width_coverflow), 
                    app.getResources().getDimensionPixelSize(R.dimen.height_coverflow)));

and in res folder specify different values width_coverflow for the different screens: values-sw600dp-land, values-sw720dp and so on...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top