2017-05-10 2 views
1

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); 
    } 
} 

Antwort

0

Ich bin nicht sicher, aber u folgenden Code nach Ansicht innerhalb verschachtelter Scroll

viewlayoutInsidescrollview.setNestedScrollingEnabled(false); 

in Java-Klasse

+0

Dank, aber es funktioniert nicht verwenden können, Arbeiter – lee

Verwandte Themen