Android 滑動效果進階篇(六)—— 倒影效果

來源:互聯網
上載者:User

上篇介紹了使用Animation實現3D動畫旋轉翻頁效果,現在介紹圖片倒影實現,先看

本樣本主要通過自訂Gallery和ImageAdapter(繼承自BaseAdapter)實現

1、倒影繪製

ImageAdapter繼承自BaseAdapter,詳細實現可見 Android 滑動效果入門篇(二)—— Gallery 這裡重點介紹倒影原理及實現

倒影原理:

倒影效果是主要由原圖+間距+倒影三部分組成,高度大約為原圖的3/2(原圖為1、倒影為1/2)

原圖,就是我們看到了最開始的圖片

間距,是原圖與倒影之間的間隙,如:reflectionGap = 4;

倒影,是原圖下半部分1/2高度,通過矩陣變換matrix.preScale(1, -1); 擷取倒立圖片,然後再加上線性遮罩和陰影實現

倒影實現:

/** 反射倒影 */<br />public boolean createReflectedImages() {<br />final int reflectionGap = 4;<br />int index = 0;<br />for (Map<String, Object> map : list) {<br />Integer id = (Integer) map.get("image");<br />Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), id);// 擷取原始圖片<br />int width = originalImage.getWidth();<br />int height = originalImage.getHeight();</p><p>Matrix matrix = new Matrix();<br />matrix.preScale(1, -1);// 圖片矩陣變換(從低部向頂部的倒影)<br />Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height/2, width, height/2, matrix, false);// 截取原圖下半部分<br />Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888);// 建立倒影圖片(高度為原圖3/2)</p><p>Canvas canvas = new Canvas(bitmapWithReflection);// 繪製倒影圖(原圖 + 間距 + 倒影)<br />canvas.drawBitmap(originalImage, 0, 0, null);// 繪製原圖<br />Paint paint = new Paint();<br />canvas.drawRect(0, height, width, height + reflectionGap, paint);// 繪製原圖與倒影的間距<br />canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);// 繪製倒影圖</p><p>paint = new Paint();<br />LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);<br />paint.setShader(shader);// 線性漸層效果<br />paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));// 倒影遮罩效果<br />canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);// 繪製倒影的陰影製作效果</p><p>ImageView imageView = new ImageView(mContext);<br />imageView.setImageBitmap(bitmapWithReflection);// 設定倒影圖片<br />imageView.setLayoutParams(new myGallery.LayoutParams(180, 240));<br />imageView.setScaleType(ScaleType.MATRIX);<br />mImages[index++] = imageView;<br />}<br />return true;<br />}

2、myGallery

自訂Gallery來實現倒影圖片的瀏覽與選擇

public class myGallery extends Gallery {</p><p>private Camera mCamera = new Camera();<br />private int mMaxRotationAngle = 60;// 最大旋轉角度 60<br />private int mMaxZoom = -120;<br />private int mCoveflowCenter;</p><p>public myGallery(Context context) {<br />super(context);<br />this.setStaticTransformationsEnabled(true);<br />}</p><p>public myGallery(Context context, AttributeSet attrs) {<br />super(context, attrs);<br />this.setStaticTransformationsEnabled(true);<br />}</p><p>public myGallery(Context context, AttributeSet attrs, int defStyle) {<br />super(context, attrs, defStyle);<br />this.setStaticTransformationsEnabled(true);<br />}</p><p>public int getMaxRotationAngle() {<br />return mMaxRotationAngle;<br />}</p><p>public void setMaxRotationAngle(int maxRotationAngle) {<br />mMaxRotationAngle = maxRotationAngle;<br />}</p><p>public int getMaxZoom() {<br />return mMaxZoom;<br />}</p><p>public void setMaxZoom(int maxZoom) {<br />mMaxZoom = maxZoom;<br />}</p><p>/** 擷取Gallery的中心x */<br />private int getCenterOfCoverflow() {<br />return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();<br />}</p><p>/** 擷取View的中心x */<br />private static int getCenterOfView(View view) {<br />return view.getLeft() + view.getWidth() / 2;<br />}</p><p>@Override<br />protected void onSizeChanged(int w, int h, int oldw, int oldh) {<br />mCoveflowCenter = getCenterOfCoverflow();<br />super.onSizeChanged(w, h, oldw, oldh);<br />}</p><p>@Override<br />protected boolean getChildStaticTransformation(View child, Transformation trans) {<br />final int childCenter = getCenterOfView(child);<br />final int childWidth = child.getWidth();<br />int rotationAngle = 0;</p><p>trans.clear();<br />trans.setTransformationType(Transformation.TYPE_BOTH);// alpha 和 matrix 都變換</p><p>if (childCenter == mCoveflowCenter) {// 正中間的childView<br />transformImageBitmap((ImageView) child, trans, 0);<br />} else {// 兩側的childView<br />rotationAngle = (int) ( ( (float) (mCoveflowCenter - childCenter) / childWidth ) * mMaxRotationAngle );<br />if (Math.abs(rotationAngle) > mMaxRotationAngle) {<br />rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;<br />}<br />transformImageBitmap((ImageView) child, trans, rotationAngle);<br />}</p><p>return true;<br />}</p><p>private void transformImageBitmap(ImageView child, Transformation trans, int rotationAngle) {<br />mCamera.save();</p><p>final Matrix imageMatrix = trans.getMatrix();<br />final int imageHeight = child.getLayoutParams().height;<br />final int imageWidth = child.getLayoutParams().width;<br />final int rotation = Math.abs(rotationAngle);</p><p>// 在Z軸上正向移動camera的視角,實際效果為放大圖片; 如果在Y軸上移動,則圖片上下移動; X軸上對應圖片左右移動。<br />mCamera.translate(0.0f, 0.0f, 100.0f);</p><p>// As the angle of the view gets less, zoom in<br />if (rotation < mMaxRotationAngle) {<br />float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));<br />mCamera.translate(0.0f, 0.0f, zoomAmount);<br />}</p><p>mCamera.rotateY(rotationAngle);// rotationAngle 為正,沿y軸向內旋轉; 為負,沿y軸向外旋轉</p><p>mCamera.getMatrix(imageMatrix);<br />imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));<br />imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));</p><p>mCamera.restore();<br />}<br />}
3、Activity

Activity中,主要實現自訂Gallery的圖片填充ImageAdapter、myGallery選擇事件監聽、點擊事件監聽

private void initRes(){<br />tvTitle = (TextView) findViewById(R.id.tvTitle);<br />gallery = (myGallery) findViewById(R.id.mygallery);// 擷取自訂的myGallery控制項</p><p>adapter = new ImageAdapter(this);<br />adapter.createReflectedImages();// 建立倒影效果<br />gallery.setAdapter(adapter);</p><p>gallery.setOnItemSelectedListener(new OnItemSelectedListener() {// 設定選擇事件監聽<br />@Override<br />public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {<br />tvTitle.setText(adapter.titles[position]);<br />}</p><p>@Override<br />public void onNothingSelected(AdapterView<?> parent) {<br />}<br />});</p><p>gallery.setOnItemClickListener(new OnItemClickListener() {// 設定點擊事件監聽<br />@Override<br />public void onItemClick(AdapterView<?> parent, View view, int position, long id) {<br />Toast.makeText(Main.this, "img " + (position+1) + " selected", Toast.LENGTH_SHORT).show();<br />}<br />});<br />}

main.xml布局檔案中,通過實現自訂的myGallery,來顯示圖片集合

<?xml version="1.0" encoding="utf-8"?><br /><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"<br /> android:orientation="vertical" ><br /> <TextView<br /> android:id="@+id/tvTitle"<br /> android:layout_width="wrap_content"<br /> android:layout_height="wrap_content"<br /> android:layout_centerHorizontal="true"<br /> android:textSize="16sp" /></p><p> <com.homer.reflect.myGallery<br /> android:id="@+id/mygallery"<br /> android:layout_width="fill_parent"<br /> android:layout_height="wrap_content"<br /> android:layout_below="@id/tvTitle"<br /> android:layout_marginTop="10dip" /><br /></RelativeLayout>

源碼下載

參考推薦:

Android實現圖片的倒影效果

Android中圖片倒影、圓角效果重繪

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.