自定义CoordinatorLayout.Behavior类

时间:2017-09-14 14:08:05

标签: android-coordinatorlayout android-collapsingtoolbarlayout android-appbarlayout coordinator-layout

我正在尝试自定义CoordinatorLayout.Behavior类。下面的图片会告诉您目前的工作情况。

ImageOne

ImageTwo

ImageThree

AVATAR 图片,即用户的个人资料图片,目前正在向左滚动。我想向右滚动它。我遵循了this教程。我试过的是下面的内容。我知道我需要自定义 CustomBehaviourForAvatarImg 类的 onDependentViewChanged 方法。但我完全糊涂了,不知道该怎么做。

以下是我的尝试。

activity_main.xml中

    public class MainActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener {

    private boolean mIsTheTitleVisible = false;
    private boolean mIsThePersonDetailsContainerVisible = true;

    private static final int ALPHA_ANIMATIONS_DURATION = 200;
    private static final float PERCENTAGE_TO_HIDE_PERSON_DETAILS = 0.3f;
    private static final float PERCENTAGE_TO_SHOW_TITLE_AT_TOOLBAR = 0.9f;

    private TextView tvTitleToolBar;
    private AppBarLayout appBarLayout;
    private LinearLayout linearLayoutPersonDetails;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById();

        appBarLayout.addOnOffsetChangedListener(this);

        startAlphaAnimation(tvTitleToolBar, 0, View.INVISIBLE);
    }

    private void findViewById() {
        tvTitleToolBar = (TextView) findViewById(R.id.tvTitleToolBar);
        appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
        linearLayoutPersonDetails = (LinearLayout) findViewById(R.id.linearLayout);
    }

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

        int maxScroll = appBarLayout.getTotalScrollRange();
        float percentage = (float) Math.abs(verticalOffset) / (float) maxScroll;

        handleAlphaOnPersonDetails(percentage);
        handleToolBarTitleVisibility(percentage);
    }

    public static void startAlphaAnimation(View v, long duration, int visibility) {
        AlphaAnimation alphaAnimation = (visibility == View.VISIBLE)
                ? new AlphaAnimation(0f, 1f)
                : new AlphaAnimation(1f, 0f);

        alphaAnimation.setDuration(duration);
        alphaAnimation.setFillAfter(true);
        v.startAnimation(alphaAnimation);
    }

    private void handleAlphaOnPersonDetails(float percentage) {

        if (percentage >= PERCENTAGE_TO_HIDE_PERSON_DETAILS) {
            if (mIsThePersonDetailsContainerVisible) {
                startAlphaAnimation(linearLayoutPersonDetails, ALPHA_ANIMATIONS_DURATION, View.INVISIBLE);
                mIsThePersonDetailsContainerVisible = false;
            }
        } else {
            if (!mIsThePersonDetailsContainerVisible) {
                startAlphaAnimation(linearLayoutPersonDetails, ALPHA_ANIMATIONS_DURATION, View.VISIBLE);
                mIsThePersonDetailsContainerVisible = true;
            }
        }
    }

    private void handleToolBarTitleVisibility(float percentage) {

        if (percentage >= PERCENTAGE_TO_SHOW_TITLE_AT_TOOLBAR) {
            if (!mIsTheTitleVisible) {
                startAlphaAnimation(tvTitleToolBar, ALPHA_ANIMATIONS_DURATION, View.VISIBLE);
                mIsTheTitleVisible = true;
            }
        } else {
            if (mIsTheTitleVisible) {
                startAlphaAnimation(tvTitleToolBar, ALPHA_ANIMATIONS_DURATION, View.INVISIBLE);
                mIsTheTitleVisible = false;
            }
        }
    }
}

MainActivity.java

    public class CustomBehaviourForAvatarImg extends CoordinatorLayout.Behavior<CircleImageView> {

    private final Context mContext;

    private int mStartChildXPosition;
    private int mEndChildXPosition;

    private int mStartDependencyYPosition;
    private int mEndDependencyYPosition;

    private int mStartChildHeight;
    private int mEndChildHeight;

    private float mStartToolBarPosition;

    public CustomBehaviourForAvatarImg(Context context, AttributeSet attrs) {
        this.mContext = context;
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, CircleImageView child, View dependency) {
        return dependency instanceof Toolbar;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency) {

        initProperties(child, dependency);

        final int maxScrollDistance = (int) (mStartToolBarPosition - getStatusBarHeight());
        float expandedPercentageFactor = dependency.getY() / maxScrollDistance;

        float distanceYToSubtract = ((mStartDependencyYPosition - mEndDependencyYPosition)
                * (1f - expandedPercentageFactor)) + (child.getHeight() / 2);

        float distanceXToSubtract = ((mStartChildXPosition - mEndChildXPosition)
                * (1f - expandedPercentageFactor)) + (child.getWidth() / 2);

        float heightToSubtract = ((mStartChildHeight - mEndChildHeight) * (1f - expandedPercentageFactor));

        child.setY(mStartDependencyYPosition - distanceYToSubtract);
        child.setX(mStartChildXPosition - distanceXToSubtract);

        CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();

        lp.width = (int) (mStartChildHeight - heightToSubtract);
        lp.height = (int) (mStartChildHeight - heightToSubtract);

        child.setLayoutParams(lp);

        return true;
    }

    private void initProperties(CircleImageView child, View dependency) {

        if (mStartChildHeight == 0)
            mStartChildHeight = child.getHeight();

        if (mEndChildHeight == 0)
            mEndChildHeight = mContext.getResources().getDimensionPixelOffset(R.dimen.image_small_width);

        if (mStartChildXPosition == 0)
            mStartChildXPosition = (int) (child.getX() + (child.getWidth() / 2));

        if (mEndChildXPosition == 0)
            mEndChildXPosition = mContext.getResources().getDimensionPixelOffset(R.dimen.abc_action_bar_content_inset_material) + (mEndChildHeight / 2);

        if (mStartDependencyYPosition == 0)
            mStartDependencyYPosition = (int) (dependency.getY());

        if (mEndDependencyYPosition == 0)
            mEndDependencyYPosition = (dependency.getHeight() / 2);

        if (mStartToolBarPosition == 0)
            mStartToolBarPosition = dependency.getY() + (dependency.getHeight() / 2);
    }

    public int getStatusBarHeight() {

        int result = 0;
        int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");

        if (resourceId > 0) {
            result = mContext.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
}

CustomBehaviourForAvatarImg.java

{{1}}

提前致谢!

0 个答案:

没有答案