Ich erstelle eine Scroll-Aktivität in meiner Android App. Die Aktivität verfügt über eine CollapsingToolbarLayout mit Parallax-Effekt.CollapsingToolbarLayout Scrollender Bug - Manchmal bleibt er beim Scrollen hängen
Wenn ich das Layout unterhalb des Appbarlayouts scrolle, wird es glatt nach oben gehen und das Appbarlayout wird bis zum Titel reduziert. Die ImageView und die TextView gehen bis zum Titel hoch. Und wenn ich das Layout zurückscrolle, werden alle wieder zum Anfang zurückgehen.
Der Fehler ist hier:
, wenn ich die Aktivität auf einigen Geräten laufen, manchmal, wenn ich es nach oben, wird das Layout stucked da sein für Sekunden nach oben und unten und dann nach oben, zurück. Und wenn ich die Aktivität auf einigen anderen Geräten ausführe, wird es in Ordnung sein, nichts ist passiert.
Die Demo von diesem Fehler: https://share.weiyun.com/1d797a4a92580e1595eacb226f9a92a3
Hier ist das Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="nczz.cn.helloworld.ScrollingActivity"
>
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:background="#FA7199"
app:layout_scrollFlags="scroll|enterAlways"
android:theme="@style/AppTheme.AppBarOverlay">
<nczz.cn.widget.CollapsingImageTextLayout
android:id="@+id/imageTextLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title_id="@+id/test_title"
app:text_id="@+id/test_text"
app:img_scale="0.6"
app:text_scale="0.6"
app:text_margin_left="110dp"
app:img_id="@+id/test_img"
app:img_margin_left="55dp"
>
<LinearLayout
android:id="@+id/test_title"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#FA7199"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/return_btn"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginLeft="20dp"
android:layout_centerVertical="true"
android:src="@drawable/left" />
</LinearLayout>
<ImageView
android:id="@+id/test_img"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher"
android:layout_centerInParent="true"
android:layout_marginBottom="30dp"
/>
<TextView
android:id="@+id/test_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/test_img"
android:text="MoveText"
android:textSize="20sp"
android:textColor="@android:color/white"
android:layout_marginTop="-20dp"
android:layout_marginLeft="50dp"
android:layout_centerInParent="true"
/>
</nczz.cn.widget.CollapsingImageTextLayout>
</android.support.design.widget.AppBarLayout>
<include
android:id="@+id/includelayout"
layout="@layout/content_scrolling"/>
</android.support.design.widget.CoordinatorLayout>
Hier ist die CollapsingImageTextLayout:
package nczz.cn.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.NonNull;
import android.support.design.widget.AppBarLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.RelativeLayout;
import nczz.cn.helloworld.R;
/**
* Created by yahui.hu on 2017/4/21.
*/
public class CollapsingImageTextLayout extends RelativeLayout {
private AppBarLayout.OnOffsetChangedListener mOffsetChangedListener;
private int mTitleId, mTextId, mImageId;
private int mTitleMarginLeft, mTitleMarginTop, mImgMarginLeft, mImgMarginTop;
private float mTextScale, mImgScale;
private View mTitle, mImg, mText;
private boolean isGetView = true;
private int mTitleHeight = 0;
public CollapsingImageTextLayout(Context context) {
this(context, null);
}
public CollapsingImageTextLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CollapsingImageTextLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CollapsingImageLayout, defStyleAttr, 0);
mTitleId = a.getResourceId(R.styleable.CollapsingImageLayout_title_id, 0);
mTextId = a.getResourceId(R.styleable.CollapsingImageLayout_text_id, 0);
mImageId = a.getResourceId(R.styleable.CollapsingImageLayout_img_id, 0);
mTextScale = a.getFloat(R.styleable.CollapsingImageLayout_text_scale, 0.4f);
mImgScale = a.getFloat(R.styleable.CollapsingImageLayout_img_scale, 0.4f);
mTitleMarginLeft = a.getDimensionPixelSize(R.styleable.CollapsingImageLayout_text_margin_left, 0);
mTitleMarginTop = a.getDimensionPixelSize(R.styleable.CollapsingImageLayout_text_margin_top, 0);
mImgMarginLeft = a.getDimensionPixelSize(R.styleable.CollapsingImageLayout_img_margin_left, 0);
mImgMarginTop = a.getDimensionPixelSize(R.styleable.CollapsingImageLayout_img_margin_top, 0);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
getView();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void getView() {
if (!isGetView) {
return;
}
if (mTitleId != 0) {
mTitle = findViewById(mTitleId);
}
if (mTextId != 0) {
mText = findViewById(mTextId);
}
if (mImageId != 0) {
mImg = findViewById(mImageId);
}
isGetView = false;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (mTitle != null) {
getViewOffsetHelper(mTitle).onViewLayout(0, 0);
setMinimumHeight(getHeightWithMargins(mTitle));
mTitleHeight = mTitle.getHeight();
this.bringChildToFront(mTitle);
}
if (mImg != null) {
getViewOffsetHelper(mImg).onViewLayout(mImgMarginLeft, mImgMarginTop);
this.bringChildToFront(mImg);
}
if (mText != null) {
getViewOffsetHelper(mText).onViewLayout(mTitleMarginLeft, mTitleMarginTop);
this.bringChildToFront(mText);
}
}
static ViewHelper getViewOffsetHelper(View view) {
ViewHelper offsetHelper = (ViewHelper) view.getTag(R.id.view_helper);
if (offsetHelper == null) {
offsetHelper = new ViewHelper(view);
view.setTag(R.id.view_helper, offsetHelper);
}
return offsetHelper;
}
private static int getHeightWithMargins(@NonNull final View view) {
final ViewGroup.LayoutParams lp = view.getLayoutParams();
if (lp instanceof MarginLayoutParams) {
final MarginLayoutParams mlp = (MarginLayoutParams) lp;
return view.getHeight() + mlp.topMargin + mlp.bottomMargin;
}
return view.getHeight();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ViewParent viewParent = getParent();
if (viewParent instanceof AppBarLayout) {
if (mOffsetChangedListener == null) mOffsetChangedListener = new OffsetListenerImp();
((AppBarLayout) viewParent).addOnOffsetChangedListener(mOffsetChangedListener);
}
}
@Override
protected void onDetachedFromWindow() {
ViewParent viewParent = getParent();
if (viewParent instanceof AppBarLayout) {
((AppBarLayout) viewParent).removeOnOffsetChangedListener(mOffsetChangedListener);
}
super.onDetachedFromWindow();
}
final int getMaxOffsetForPinChild(View child) {
final ViewHelper offsetHelper = getViewOffsetHelper(child);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
return getHeight()
- offsetHelper.getLayoutTop()
- child.getHeight()
- lp.bottomMargin;
}
static int constrain(int amount, int low, int high) {
return amount < low ? low : (amount > high ? high : amount);
}
static int constrain(int amount, int low) {
return amount < low ? low : amount;
}
private void setTopAndBottomOffset(View child, int verticalOffset) {
ViewHelper viewHelper = (ViewHelper) child.getTag(R.id.view_helper);
viewHelper.setTopAndBottomOffset(
constrain(-verticalOffset, 0, getMaxOffsetForPinChild(child)));
Log.e("setTopAndBottomOffset",""+-verticalOffset);
}
private void setTopAndBottomOffset(View child, int verticalOffset, float scale) {
ViewHelper viewHelper = (ViewHelper) child.getTag(R.id.view_helper);
viewHelper.setTopAndBottomOffset(
constrain(-verticalOffset - getMaxOffset(viewHelper, scale),
0));
//Log.e("setTopAndBottomOffset",""+-verticalOffset);
}
private void setLeftAndRightOffset(View child, int verticalOffset, float scale) {
ViewHelper viewHelper = (ViewHelper) child.getTag(R.id.view_helper);
int maxOffsetDistance = getMaxOffset(viewHelper, scale);
int maxLeft = viewHelper.getLayoutLeft()
+ (viewHelper.getViewWidth() - viewHelper.getScaleViewWidth(scale))
- viewHelper.getMarginTitleLeft();
int realOffset = (int) (maxLeft * 1.0f/(maxOffsetDistance * 1.0f) * verticalOffset);
realOffset = constrain(realOffset, -maxLeft, maxLeft);
viewHelper.setLeftAndRightOffset(realOffset);
// Log.e("setLeftAndRightOffset",""+realOffset);
}
private void setViewScale(View child, int verticalOffset, float scale) {
ViewHelper viewHelper = (ViewHelper) child.getTag(R.id.view_helper);
int maxOffsetDistance = getMaxOffset(viewHelper, scale);
float realScale = -verticalOffset - maxOffsetDistance > 0 ? scale : verticalOffset == 0 ? 1f : 0f;
if (realScale == 0) {
realScale = (maxOffsetDistance + verticalOffset * (1 - scale))/(maxOffsetDistance * 1f);
}
viewHelper.setViewOffsetScale(realScale);
}
private int getMaxOffset(ViewHelper viewHelper, float scale) {
int scaleViewHeight = (int) (scale * viewHelper.getViewHeight());
int offsetTitleDistance = scaleViewHeight >= mTitleHeight ? 0 : (mTitleHeight - scaleViewHeight)/2;
int marginTop = viewHelper.getMarginTitleTop() >= offsetTitleDistance ? offsetTitleDistance : viewHelper.getMarginTitleTop();
return viewHelper.getLayoutBottom() - viewHelper.getScaleViewHeight(scale) - offsetTitleDistance - marginTop;
}
private class OffsetListenerImp implements AppBarLayout.OnOffsetChangedListener {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (mTitle != null) {
setTopAndBottomOffset(mTitle, verticalOffset);
}
if (mText != null) {
setTopAndBottomOffset(mText, verticalOffset, mTextScale);
setLeftAndRightOffset(mText, verticalOffset, mTextScale);
setViewScale(mText, verticalOffset, mTextScale);
}
if (mImg != null) {
setTopAndBottomOffset(mImg, verticalOffset, mImgScale);
setLeftAndRightOffset(mImg, verticalOffset, mImgScale);
setViewScale(mImg, verticalOffset, mImgScale);
}
}
}
public void setImgTitleMarginTop(int top) {
if (mImg != null) {
getViewOffsetHelper(mImg).setMarginTitleTop(top);
}
}
public void setImgTitleMarginLeft(int left) {
if (mImg != null) {
getViewOffsetHelper(mImg).setMarginTitleLeft(left);
}
}
public void setTextTitleMarginTop(int top) {
if (mText != null) {
getViewOffsetHelper(mText).setMarginTitleTop(top);
}
}
public void setImgTextMarginLeft(int left) {
if (mText != null) {
getViewOffsetHelper(mText).setMarginTitleLeft(left);
}
}
}
Hier ist die content_scolling.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="#cccccc"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="nczz.cn.helloworld.ScrollingActivity"
tools:showIn="@layout/activity_scrolling">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/large_text" />
</android.support.v4.widget.NestedScrollView>
Hier ist die Java:
package nczz.cn.helloworld;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
public class ScrollingActivity extends Activity {
LinearLayout titleTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_scrolling);
initViews();
setTitleBarHeight();
}
private void initViews(){
titleTxt= (LinearLayout) findViewById(R.id.test_title);
}
private void setTitleBarHeight(){
WindowManager manager=getWindowManager();
int height=manager.getDefaultDisplay().getHeight();
ViewGroup.LayoutParams params=titleTxt.getLayoutParams();
params.height=height/12;
titleTxt.setLayoutParams(params);
}
}
Dank, aber es funktioniert nicht verwenden können, Arbeiter – lee