【问题标题】:ViewPager with Rotational transformation带有旋转变换的 ViewPager
【发布时间】:2017-05-13 18:04:35
【问题描述】:

我想创建ViewPager,它在滑动时围绕getWidth()getHeight() 轴旋转。我试过了,但所有这些转换都只能通过具有各种效果的垂直和水平来实现。

有什么方法或提示可以开发这种ViewPager吗?

EDIT- 说明旋转方式

Axis - getWidth, getHeight 应该是枢轴点,一旦我滑动它就应该从它旋转,对于下一页它应该从 (0, getHeight) 轴旋转。 为简化起见,请考虑这个简单的场景 -

  1. 有一个圆圈,里面有 4 个部分
  2. 目前仅显示 1 个部分,其他 3 个在屏幕外
  3. 从右向左滑动后,ViewPager 应该会从第 1 页旋转到第 2 页。
  4. 如果我从左向右滑动,ViewPager 应该从第 1 页旋转到第 4 页。
  5. 退出和进入页面每次都应从该圆的中心旋转。
  6. 圆心在第一页的getWidthgetHeight。因此,对于下一页,它将始终以 0getHeight 作为轴,对于上一页,将始终以 getWidth0 作为轴。

【问题讨论】:

  • 而且没有 cmets 可以投反对票!

标签: android android-viewpager android-view


【解决方案1】:

更新 据我所知,你想要这样的过渡。如下所示,实现了ViewPager.PageTransformer

这是ViewPager.PageTransformer 类:

public class RotationCircleTransformer implements ViewPager.PageTransformer {


    public RotationCircleTransformer() {
    }

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();
        view.setPivotX((float) pageWidth);
        view.setPivotY((float) pageHeight);

        if (position < -1) { //[-infinity,1)
            //off to the left by a lot
            view.setRotation(0);
            view.setAlpha(0);
        } else if (position <= 1) { //[-1,1]
            view.setTranslationX((-position) * pageWidth); //shift the view over
            view.setRotation(position * (90)); //rotate it
            // Fade the page relative to its distance from the center
            view.setAlpha(Math.max(1, 1 - Math.abs(position) / 3));
        } else { //(1, +infinity]
            //off to the right by a lot
            view.setRotation(0);
            view.setAlpha(0);
        }
    }
}

background_quarter.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size android:height="300dp" android:width="300dp"/>
    <solid android:color="#00F"/>
    <corners android:topLeftRadius="300dp" android:topRightRadius="0dp" android:bottomRightRadius="0dp" android:bottomLeftRadius="0dp"/>
</shape>

activity_circle_pager.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_gravity="center"
        android:layout_width="300dp"
        android:layout_height="300dp" />


</FrameLayout>

fragment_content.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:id="@+id/bg"
    android:background="@drawable/background_quarter">

    <TextView
        android:id="@+id/text"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="40dp"
        android:textColor="@android:color/white"
        android:text="" />

</FrameLayout>

CircleFragment.class

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;


public class CircleFragment extends Fragment {

    private String typeString;

    public CircleFragment() {
    }

    public static CircleFragment newInstance(String type) {
        CircleFragment fragment = new CircleFragment();
        Bundle args = new Bundle();
        args.putString("type", type);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            typeString = getArguments().getString("type","1");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_content, container, false);
        ;
        TextView text = (TextView) view.findViewById(R.id.text);
        FrameLayout bg = (FrameLayout) view.findViewById(R.id.bg);
        switch (typeString) {
            case "1":
                bg.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.background_quarter));
                break;
            case "2":
                bg.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.background_quarter));
                break;
            case "3":
                bg.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.background_quarter));
                break;
            case "4":
                bg.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.background_quarter));
                break;
        }
        text.setText(typeString);
        return view;
    }

}

CirclePagerActivity.class

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;

public class CirclePagerActivity extends AppCompatActivity {

    ViewPager mPager;
    CirclePagerAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_circle_pager);
        mPager = (ViewPager) findViewById(R.id.pager);
        List<Fragment> fragments = new ArrayList<>();
        fragments.add(ContentFragment.newInstance("1"));
        fragments.add(ContentFragment.newInstance("2"));
        fragments.add(ContentFragment.newInstance("3"));
        fragments.add(ContentFragment.newInstance("4"));
        mAdapter = new CirclePagerAdapter(getSupportFragmentManager(), fragments);
        mPager.setAdapter(mAdapter);

        mPager.setPageTransformer(true, new RotationCircleTransformer());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    static class CirclePagerAdapter extends FragmentStatePagerAdapter {

        List<Fragment> mFrags = new ArrayList<>();

        public CirclePagerAdapter(FragmentManager fm, List<Fragment> frags) {
            super(fm);
            mFrags = frags;
        }

        @Override
        public Fragment getItem(int position) {
            int index = position % mFrags.size();
            return mFrags.get(index);
        }

        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

    }
}

如果没有找到合适的ViewPager变换动画,可以实现自己的ViewPager.PageTransformer

There is 很多信息和多个示例。

还有here你可以找到有用的教程。


你能详细解释一下这部分吗?我会根据你的解释更新我的答案(Visual解释更好)。

围绕它的 getWidth() 和 getHeight() 轴旋转。

【讨论】:

  • 我已经浏览过的那些链接。对于解释部分,请查看问题,我已对其进行了编辑
  • 酷……这就是我要找的 GIF……让我试试看。完成后将投票并正确回答。谢谢:)
  • 酷它工作。很抱歉不能像在旅行中那样早点给你投票。
  • 嗯,我不太明白 - 是否可以使用这种转换围绕位于可见屏幕外部的轴旋转?即,视图是否允许 pivotX/Y 大于屏幕尺寸?
  • @Antek,旋转轴点不在屏幕之外,是的,您可以将视图和轴点放在可见屏幕之外,我确实用手机制作了这个 gif。您可以制作比这更复杂的动画。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 2022-01-26
  • 1970-01-01
相关资源
最近更新 更多