2016年9月19日 星期一

Viewfliper 會輪播的圖片功能


Ref  1 :  http://www.learn-android-easily.com/2013/06/android-viewflipper-example.html

Ref  2:  http://stackoverflow.com/questions/10200256/out-of-memory-error-imageview-issue

Ref  3:  http://abhiandroid.com/ui/viewflipper



Prerequisite for this Example
You must know how handle Swap event on screen, if not read the post How to Detect Left to Right and Right to Left Swap Event

For this Example we need Animation Resources to animate the Screen.

We have used following  Animation in this Example

in_from_left.xml
in_from_right.xml
out_to_left.xml
out_to_right.xml

These animation files must be present in your anim folder.

Create an "anim" folder inside res folder in your application and put all 4 animation files inside anim folder.

in_from_left.xml


<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromXDelta="-100%" android:toXDelta="0%"
           android:fromYDelta="0%" android:toYDelta="0%"
           android:duration="1400" />
</set>

 in_from_right.xml


<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromXDelta="100%" android:toXDelta="0%"
           android:fromYDelta="0%" android:toYDelta="0%"
           android:duration="1400" />
</set>

out_to_left.xml


<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
      <translate android:fromXDelta="0%" android:toXDelta="-100%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="1400"/>
</set>

out_to_right.xml


<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
      <translate android:fromXDelta="0%" android:toXDelta="100%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="1400"/>
</set>

view_flipper_main.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

        <TextView
            android:layout_marginTop="10dp"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textColor="#000099"
            android:textSize="30dp"
            android:text="View Flipper Demo" />

        <ViewFlipper
            android:id="@+id/view_flipper"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_margin="6dip" >
          
        <!--  The child Views/Layout to flip -->
      
        <!--  Layout 1 for 1st Screen -->

            <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:gravity="center"
                    android:orientation="vertical" >

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="15dp"
                        android:text="This Is Screen 1"
                        android:textColor="#191975"
                        android:textSize="25dp"
                        android:textStyle="bold" >
                    </TextView>

                    <ImageView
                        android:layout_marginTop="15dp"
                        android:id="@+id/imageView1"
                        android:layout_width="450dp"
                        android:layout_height="450dp"
                        android:src="@drawable/image1" />
                  
            </LinearLayout>
          
             <!--  Layout 2 for 2nd Screen -->
          
            <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:gravity="center"
                    android:orientation="vertical" >

                    <TextView
                        android:layout_marginTop="15dp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="This Is Screen 2"
                        android:textColor="#191975"
                        android:textSize="25dp"
                        android:textStyle="bold" >
                    </TextView>

                    <ImageView
                        android:layout_marginTop="15dp"
                        android:id="@+id/imageView1"
                        android:layout_width="450dp"
                        android:layout_height="450dp"
                        android:src="@drawable/image3" />
                  
            </LinearLayout>


        </ViewFlipper>

</LinearLayout>


ViewFlipperMainActivity .java


public class ViewFlipperMainActivity extends Activity
{
            private ViewFlipper viewFlipper;
            private float lastX;

            @Override
            protected void onCreate(Bundle savedInstanceState)
            {
                         super.onCreate(savedInstanceState);
                         setContentView(R.layout.view_flipper_main);
                         viewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);
            }

          
                      
            // Method to handle touch event like left to right swap and right to left swap
            public boolean onTouchEvent(MotionEvent touchevent)
            {
                         switch (touchevent.getAction())
                         {
                                // when user first touches the screen to swap
                                 case MotionEvent.ACTION_DOWN:
                                 {
                                     lastX = touchevent.getX();
                                     break;
                                }
                                 case MotionEvent.ACTION_UP:
                                 {
                                     float currentX = touchevent.getX();
                                   
                                     // if left to right swipe on screen
                                     if (lastX < currentX)
                                     {
                                          // If no more View/Child to flip
                                         if (viewFlipper.getDisplayedChild() == 0)
                                             break;
                                       
                                         // set the required Animation type to ViewFlipper
                                         // The Next screen will come in form Left and current Screen will go OUT from Right 

                                         viewFlipper.setInAnimation(this, R.anim.in_from_left);
                                         viewFlipper.setOutAnimation(this, R.anim.out_to_right);
                                         // Show the next Screen
                                         viewFlipper.showNext();
                                     }
                                   
                                     // if right to left swipe on screen
                                     if (lastX > currentX)
                                     {
                                         if (viewFlipper.getDisplayedChild() == 1)
                                             break;
                                         // set the required Animation type to ViewFlipper
                                         // The Next screen will come in form Right and current Screen will go OUT from Left 

                                         viewFlipper.setInAnimation(this, R.anim.in_from_right);
                                         viewFlipper.setOutAnimation(this, R.anim.out_to_left);
                                         // Show The Previous Screen
                                         viewFlipper.showPrevious();
                                     }
                                     break;
                                 }
                         }
                         return false;
            }

 }


但是因為他是直接在 xml 裡面指定 image src..  如果你改成3張..  然後一次解3張..就會爆掉

這時候就必須換個作法  Ref2

加入這兩個副程式... 其意思是說用resource 的方式來解bmp.... 然後會先算出縮放比例...

更新   options.inSampleSize ..  才去解碼bmp...就不會爆掉

最後調用  setImageBitmap 的function 去解碼bmp
 final ImageView iv = imageView;
 iv.setImageBitmap(
                        decodeSampledBitmapFromResource(getResources(),
                                resId, imageViewWidth, imageViewHeight));

然後我們的例子是....
img_curr.setImageBitmap(decodeSampledBitmapFromResource(getResources(),
                R.drawable.ibanner1, 400, 400));

因為我把 jbanner1 放在 drawable folder 下面

private static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds = true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

    private static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {

        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }


參考 Ref 3:

如果想要自動輪播.....  只需要指定 in 和 out 的動畫設定和  setFlipInterval(時間區隔)

然後呼叫 setAutoStart(true)就可以了


viewFlipper.setInAnimation(this,R.anim.in_from_left);
viewFlipper.setOutAnimation(this,R.anim.out_to_right);
// set interval time for flipping between viewsviewFlipper.setFlipInterval(3000);
// set auto start for flipping between viewsviewFlipper.setAutoStart(true);


==========================================================

如果想要  直接在code 裡面加入  imageview...  使用  addView(imageView);就可以

int[] images = {R.drawable.ibanner1, R.drawable.ibanner2, R.drawable.ibanner3};

for (int i = 0; i < images.length; i++) {

    // create the object of ImageView    ImageView imageView = new ImageView(this);
    imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(),
            images[i], 400, 400)); // set image in ImageView    viewFlipper.addView(imageView); // add the created ImageView in ViewFlipper}




沒有留言:

張貼留言