12

Я использую настраиваемый макет панели инструментов Collapsing, в которой есть заголовок и субтитры.
У меня получилось название, чтобы рухнуть и анимировать по искривленному пути, но часть названия становится меньше, так как рушится не гладкая. Он изменяет размеры в зазубренном виде.
Это мое поведение, которое отвечает за перемещение и изменение размеров название:Пользовательская сворачивающая панель с плавным изменением названия

public class ViewBehavior : CoordinatorLayout.Behavior 
{ 
    private Context mContext; 

    private int mStartMarginRight; 
    private int mEndMargintRight; 
    private int mMarginLeft; 
    private int mStartMarginBottom; 
    private bool isHide; 
    private static float SCALE_MINIMUM = 0.5f; 
    public ViewBehavior(Context context, IAttributeSet attrs) 
    { 
     mContext = context; 
    } 

    public override bool LayoutDependsOn(CoordinatorLayout parent, Java.Lang.Object child, View dependency) 
    { 
     return dependency is AppBarLayout; 
    } 

    public override bool OnDependentViewChanged(CoordinatorLayout parent, Java.Lang.Object child, View dependency) 
    { 
     ShouldInitProperties((child as HeaderView), dependency); 

     int maxScroll = ((AppBarLayout)dependency).TotalScrollRange; 
     float percentage = System.Math.Abs(dependency.GetY())/(float)maxScroll; 

     float childPosition = dependency.Height 
       + dependency.GetY() 
       - (child as View).Height 
       - (getToolbarHeight() - (child as View).Height) * percentage/2; 


     childPosition = childPosition - mStartMarginBottom * (1f - percentage); 

     CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)(child as View).LayoutParameters; 
     lp.RightMargin = (int)(100 * System.Math.Sin(percentage * System.Math.PI)) + mStartMarginRight/2 + mEndMargintRight/2; 
     lp.LeftMargin = mMarginLeft; 
     (child as View).LayoutParameters = lp; 

     (child as View).SetY(childPosition); 
     float x = (child as HeaderView).Title.TextSize; 
     //Here is the algorithm for setting the text size 
     (child as HeaderView).Title.SetTextSize(ComplexUnitType.Sp, 36 * (1 - percentage/2)); 
     (child as HeaderView).SubTitle.SetTextSize(ComplexUnitType.Sp, 26 * (1 - percentage/2)); 

     var toolbarTitleSize = (int)TypedValue.ApplyDimension(ComplexUnitType.Sp, 18, Application.Context.Resources.DisplayMetrics); 
     var toolbarSubTitleSize = (int)TypedValue.ApplyDimension(ComplexUnitType.Sp, 16, Application.Context.Resources.DisplayMetrics); 
     if ((child as HeaderView).Title.TextSize < toolbarTitleSize) 
      (child as HeaderView).Title.SetTextSize(ComplexUnitType.Sp, 18); 
     if ((child as HeaderView).SubTitle.TextSize < toolbarSubTitleSize) 
      (child as HeaderView).SubTitle.SetTextSize(ComplexUnitType.Sp, 14); 
     if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop) 
     { 
      if (isHide && percentage < 1) 
      { 
       (child as View).Visibility = ViewStates.Visible; 
       isHide = false; 
      } 
      else if (!isHide && percentage == 1) 
      { 
       (child as View).Visibility = ViewStates.Gone; 
       isHide = true; 
      } 
     } 
     return true; 
    } 


    public void ShouldInitProperties(HeaderView child, View dependency) 
    { 

     if (mStartMarginRight == 0) 
      mStartMarginRight = mContext.Resources.GetDimensionPixelOffset(Resource.Dimension.header_view_start_margin_right); 

     if (mEndMargintRight == 0) 
      mEndMargintRight = mContext.Resources.GetDimensionPixelOffset(Resource.Dimension.header_view_end_margin_right); 

     if (mStartMarginBottom == 0) 
      mStartMarginBottom = mContext.Resources.GetDimensionPixelOffset(Resource.Dimension.header_view_start_margin_bottom); 

     if (mMarginLeft == 0) 
      mMarginLeft = mContext.Resources.GetDimensionPixelOffset(Resource.Dimension.header_view_end_margin_left); 

    } 


    public int getToolbarHeight() 
    { 
     int result = 0; 
     TypedValue tv = new TypedValue(); 
     if (mContext.Theme.ResolveAttribute(Android.Resource.Attribute.ActionBarSize, tv, true)) 
     { 
      result = TypedValue.ComplexToDimensionPixelSize(tv.Data, mContext.Resources.DisplayMetrics); 
     } 
     return result; 
    } 
} 

Как я могу изменить алгоритм так, он должен изменить размер более гладкой моды?

Edit - Видео:
https://youtu.be/j6LseSW6h1s

+0

Пожалуйста, поделитесь видео или GIF для рваной части. Почему вы пытаетесь написать свой собственный алгоритм, когда android api предоставляет тот же функционал. –

+0

Постарайтесь взглянуть на следующее: https://github.com/ahmadmuzakki29/subtitle-collapsingtoolbar –

+0

@AnuragSingh Добавлено видео, которое показывает разницу между заголовком с субтитрами и обычным названием. Я пишу свой собственный алгоритм, поскольку по умолчанию он не для субтитров. Я не могу понять, что делать. – amitairos

ответ

2

Как упоминалось другими, масштабирование через textSize не работает на Android в анимации, поскольку оно недостаточно точное (округляет десятичные значения до целых чисел).

Если он удовлетворяет ваши потребности, вы должны выполнить анимацию с атрибутами в scaleX/scaleY и т.д .:

float scale = 1 - percentage * SCALE_MINIMUM; 
(child as HeaderView).Title.SetScaleX(scale); 
(child as HeaderView).Title.SetScaleY(scale); 
(child as HeaderView).SubTitle.SetScaleX(scale); 
(child as HeaderView).SubTitle.SetScaleY(scale); 
+0

Спасибо. Просто я изменил его на: (дочерний как HeaderView) .SetScaleX (масштаб); (ребенок как HeaderView) .SetScaleY (шкала); – amitairos

2

Проблема у вас есть то, что даже если подсчитать масштабы, как demical значений, они становятся целые значения в TextView. Вы должны активировать флаги LINEAR_TEXT_FLAG и SUBPIXEL_TEXT_FLAG в классе Paint TextView для достижения плавного масштабирования и позиционирования.

Что-то вроде этого:

yourTextView.Paint.SubpixelText = true; 
yourTextView.Paint.LinearText = true; 
+0

Спасибо. Я попробовал это, но все равно никакой разницы. Может быть, мне нужно что-то изменить и в моем алгоритме? – amitairos

+1

Вы проверили, какие значения вы действительно получаете от расчетов? Вы можете распечатать их и нарисовать график, чтобы увидеть, также ли он «зубчатый». – hankide

1

Я должен использовать этот формат макета для разрушения панели инструментов, и она работает плавно.

<android.support.design.widget.AppBarLayout 
     android:id="@+id/app_bar_layout" 
     android:layout_width="match_parent" 
     android:layout_height="@dimen/height_300dp" 
     android:background="?colorPrimary"> 

     <android.support.design.widget.CollapsingToolbarLayout 
      android:id="@+id/collapsible_Toolbar_Layout" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      app:collapsedTitleTextAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse" 
      app:contentScrim="@color/colorDarkBlue" 
      app:expandedTitleMarginEnd="@dimen/margin_64dp" 
      app:expandedTitleMarginStart="@dimen/margin_20dp" 
      app:expandedTitleTextAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse" 
      app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> 

      <ImageView 
       android:id="@+id/image" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:clickable="true" 
       android:fitsSystemWindows="true" 
       android:focusableInTouchMode="true" 
       android:scaleType="centerCrop" 
       app:layout_collapseMode="parallax" /> 

      <RelativeLayout 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:background="@color/colorTransparent" /> 

      <ImageButton 
       android:id="@+id/ib" 
       android:layout_width="@dimen/margin_35dp" 
       android:layout_height="@dimen/margin_35dp" 
       android:layout_gravity="right" 
       android:layout_marginRight="@dimen/margin_10dp" 
       android:layout_marginTop="@dimen/height_245dp" 
       android:background="@null" 
       android:src="@drawable/ic_launcher" /> 


      <android.support.v7.widget.Toolbar 
       android:id="@+id/toolbar" 
       android:layout_width="match_parent" 
       android:layout_height="?actionBarSize" 
       android:background="@android:color/transparent" 
       android:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
       app:contentInsetStart="@dimen/margin_50dp" 
       app:layout_collapseMode="pin"> 

       <ImageButton 
        android:id="@+id/ib2" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="right" 
        android:layout_marginRight="@dimen/margin_10dp" 
        android:background="@null" 
        android:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
        android:src="@drawable/ic_launcher" 
        android:visibility="invisible" /> 

      </android.support.v7.widget.Toolbar> 
     </android.support.design.widget.CollapsingToolbarLayout> 
    </android.support.design.widget.AppBarLayout> 

После этого в фрагменте в IntializeComponents я инициализировать этот макет только и набор текста

 appBarLayout = (AppBarLayout)view.findViewById(R.id.app_bar_layout); 

     CollapsingToolbarLayout toolbarLayout = (CollapsingToolbarLayout) view.findViewById(R.id.collapsible_Toolbar_Layout); 
     toolbarLayout.setTitle(yourTitle); 
     toolbarLayout.setCollapsedTitleTextColor(Color.WHITE); 
     toolbarLayout.setExpandedTitleColor(Color.WHITE); 
     appBarLayout.addOnOffsetChangedListener(this); 

Добавить этот метод Handle панель

@Override 
    public void onOffsetChanged(AppBarLayout appBarLayout, int offset) { 
     int maxScroll = appBarLayout.getTotalScrollRange(); 
     float percentage = (float) Math.abs(offset)/(float) maxScroll; 
     handleToolbarTitleVisibility(percentage); 
    } 

    private void handleToolbarTitleVisibility(float percentage) { 
     if (percentage >= PERCENTAGE_TO_SHOW_TITLE_AT_TOOLBAR) { 
      if(!mIsTheTitleVisible) { 
       imageButton.setVisibility(View.VISIBLE); 
       ib.setVisibility(View.INVISIBLE); 
       mIsTheTitleVisible = true; 
      } 

     } else { 

      if (mIsTheTitleVisible) { 
       imageButton.setVisibility(View.INVISIBLE); 
       ibMap.setVisibility(View.VISIBLE); 
       mIsTheTitleVisible = false; 
      } 
     } 
    } 

Я надеюсь, что это будет поможет вам:)

+0

Благодарим вас за усилия. Однако это не решает мою проблему.Проблема в том, что изменение размера текста не является гладким, потому что я использую собственный TextView внутри моего CollapsingToolbar. – amitairos

1

Нет, если вы используете customTextview, то он также будет работать, потому что я также используя только customTextView.

Вы разместите код пользовательского кода здесь? Таким образом, все может увидеть проблему в вашем customTextview.

+0

Это не пользовательский TextView, это TextView, который служит заголовком. Я вообще не показываю заголовок панели Collapsing Toolbar и показываю этот TextView и изменяю его размер в соответствии с процентом. – amitairos