Android中的轮播视图

时间:2013-12-27 06:30:43

标签: android carousel android-custom-view

我需要实现轮播视图。到目前为止我尝试过的是

此代码工作正常,它还显示图像gallary视图中的封面流程寻呼效果。但是这段代码中的一个问题是当图像显示在封面流程中时,当前图像可以正常显示但下一个图像在当前图像的前面看到。

我该如何解决这个问题。

主要活动

package net.leolink.android.simpleinfinitecarousel;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;

public class MainActivity extends FragmentActivity {
    public final static int PAGES = 5;
    // You can choose a bigger number for LOOPS, but you know, nobody will fling
    // more than 1000 times just in order to test your "infinite" ViewPager :D 
    public final static int LOOPS = 1000; 
    public final static int FIRST_PAGE = PAGES * LOOPS / 2;
    public final static float BIG_SCALE = 1.0f;
    public final static float SMALL_SCALE = 0.7f;
    public final static float DIFF_SCALE = BIG_SCALE - SMALL_SCALE;

    private int[] musicCover = { R.drawable.cover1, R.drawable.cover2,
            R.drawable.cover3, R.drawable.cover4, R.drawable.cover5};

    public MyPagerAdapter adapter;
    public ViewPager pager;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pager = (ViewPager) findViewById(R.id.myviewpager);

        adapter = new MyPagerAdapter(this, this.getSupportFragmentManager());
        pager.setAdapter(adapter);
        pager.setOnPageChangeListener(adapter);


        // Set current item to the middle page so we can fling to both
        // directions left and right
        pager.setCurrentItem(FIRST_PAGE);

        // Necessary or the pager will only have one extra page to show
        // make this at least however many pages you can see
        pager.setOffscreenPageLimit(3);

        // Set margin for pages as a negative number, so a part of next and 
        // previous pages will be showed
        pager.setPageMargin(-450);



    }
}

MyFragment

package net.leolink.android.simpleinfinitecarousel;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MyFragment extends Fragment {

    public static Fragment newInstance(MainActivity context, int pos, 
            float scale)
    {
        Bundle b = new Bundle();
        b.putInt("pos", pos);
        b.putFloat("scale", scale);
        return Fragment.instantiate(context, MyFragment.class.getName(), b);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }

        LinearLayout l = (LinearLayout) 
                inflater.inflate(R.layout.mf, container, false);

        int pos = this.getArguments().getInt("pos");
        /*TextView tv = (TextView) l.findViewById(R.id.text);
        tv.setText("Position = " + pos);*/

        MyLinearLayout root = (MyLinearLayout) l.findViewById(R.id.root);
        float scale = this.getArguments().getFloat("scale");
        root.setScaleBoth(scale);

        return l;
    }
}

MyLinearLayout

package net.leolink.android.simpleinfinitecarousel;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class MyLinearLayout extends LinearLayout {
    private float scale = MainActivity.BIG_SCALE;

    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyLinearLayout(Context context) {
        super(context);
    }

    public void setScaleBoth(float scale)
    {
        this.scale = scale;
        this.invalidate();  // If you want to see the scale every time you set
                            // scale you need to have this line here, 
                            // invalidate() function will call onDraw(Canvas)
                            // to redraw the view for you
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // The main mechanism to display scale animation, you can customize it
        // as your needs
        int w = this.getWidth();
        int h = this.getHeight();
        canvas.scale(scale, scale, w/2, h/2);

        super.onDraw(canvas);
    }
}

MyPagerAdapter

package net.leolink.android.simpleinfinitecarousel;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class MyPagerAdapter extends FragmentPagerAdapter implements
        ViewPager.OnPageChangeListener {

    private MyLinearLayout cur = null;
    private MyLinearLayout next = null;
    private MainActivity context;
    private FragmentManager fm;
    private float scale;

    public MyPagerAdapter(MainActivity context, FragmentManager fm) {
        super(fm);
        this.fm = fm;
        this.context = context;
    }

    @Override
    public Fragment getItem(int position) 
    {
        // make the first pager bigger than others
        if (position == MainActivity.FIRST_PAGE)
            scale = MainActivity.BIG_SCALE;         
        else
            scale = MainActivity.SMALL_SCALE;

        position = position % MainActivity.PAGES;
        return MyFragment.newInstance(context, position, scale);
    }

    @Override
    public int getCount()
    {       
        return MainActivity.PAGES * MainActivity.LOOPS;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset,
            int positionOffsetPixels) 
    {   
        if (positionOffset >= 0f && positionOffset <= 2f)
        {

            cur = getRootView(position);
            next = getRootView(position +1);


            cur.setScaleBoth(MainActivity.BIG_SCALE 
                    - MainActivity.DIFF_SCALE * positionOffset);
            next.setScaleBoth(MainActivity.SMALL_SCALE 
                    + MainActivity.DIFF_SCALE * positionOffset);
        }
    }

    @Override
    public void onPageSelected(int position) {}

    @Override
    public void onPageScrollStateChanged(int state) {}

    private MyLinearLayout getRootView(int position)
    {
        return (MyLinearLayout) 
                fm.findFragmentByTag(this.getFragmentTag(position))
                .getView().findViewById(R.id.root);
    }

    private String getFragmentTag(int position)
    {
        return "android:switcher:" + context.pager.getId() + ":" + position;
    }
}

main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#CCC"
    tools:context=".MainActivity" >

    <android.support.v4.view.ViewPager
        android:id="@+id/myviewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:overScrollMode="never" />

</RelativeLayout>

mf.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">
    <net.leolink.android.simpleinfinitecarousel.MyLinearLayout 
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center" 
        android:background="@android:color/transparent">

        <ImageView
            android:id="@+id/content"
            android:layout_width="500dp"
            android:layout_height="200dp"
            android:background="@drawable/cover3"/>
    </net.leolink.android.simpleinfinitecarousel.MyLinearLayout>
</LinearLayout>

0 个答案:

没有答案