1

Я пытаюсь закодировать свой собственный эффект параллакса, используя вид ресайклера. В настоящий момент это очень хорошо работает ... пока я не изменю ориентацию устройства.Android: Восстановление parallax recyclerview

При восстановлении состояния я возвращаю переменную «метрики», которую я использую для вычисления перевода Y в заголовке, без проблем. Но у меня возникают проблемы с ростом моих разных взглядов после восстановления.

в основном вот что я вхожу:

D/параллакса: gridHeight: 0 - панель инструментов: 0 - постер: 0

Я попытался с помощью .measure(), а затем getMeasuredHeight(), но вот что я получаю:

D/параллакса: gridHeight: 0 - панель инструментов: 128 - плакат: 1108

Возможно, я пропустил Мера. Или, может быть, я должен использовать мой метод параллакса в другой момент? (clother to runtime?) Если у вас есть какая-либо подсказка ...

Это мой первый вопрос здесь после года чтения. Надеюсь, я сделал это хорошо. И спасибо за любую помощь;)

Вот мой код:

public class ParallaxActivity extends Activity { 

    private int      metrics = 0; 
    private int      resize = 0; 
    private int      gridHeight = -1; 
    private int      toolbarHeight = -1; 
    private int      posterHeight = -1; 
    private boolean     docked = false; 

    private Toolbar     toolbar; 
    private ImageView    poster; 
    private LinearLayout   header; 
    private RecyclerView   grid; 
    private RecyclerView.LayoutManager manager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.activity_parallax2); 

    toolbar = (Toolbar)findViewById(R.id.toolbar_actionbar); 
    toolbar.setNavigationIcon(R.drawable.ic_launcher); 
    toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      finish(); 
     } 
    }); 

    poster = (ImageView)findViewById(R.id.poster); 
    grid = (RecyclerView)findViewById(R.id.list); 
    header = (LinearLayout)findViewById(R.id.header); 

    manager = new GridLayoutManager(this, 2); 
    grid.setLayoutManager(manager); 
    DefaultItemAnimator animator = new DefaultItemAnimator(); 
    grid.setItemAnimator(animator); 
    RecyclerGridAdapter ad = new RecyclerGridAdapter(this); 
    grid.setAdapter(ad); 
    ad.update(); 

    grid.setOnScrollListener(new RecyclerView.OnScrollListener() 
    { 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      super.onScrolled(recyclerView, dx, dy); 

      metrics += dy/3; 
      parallax(); 
     } 
    }); 
} 

@Override 
protected void onSaveInstanceState(Bundle b) 
{ 
    super.onSaveInstanceState(b); 
    b.putInt("metrics", metrics); 
} 

@Override 
protected void onRestoreInstanceState(Bundle b) 
{ 
    super.onRestoreInstanceState(b); 
    metrics = b.getInt("metrics", 0); 
} 

@Override 
public void onAttachedToWindow() 
{ 
    if (metrics != 0) 
     parallax(); 
} 

private void parallax() 
{ 
    if (gridHeight == -1) 
    { 
     gridHeight = grid.getHeight(); 
     toolbarHeight = toolbar.getHeight(); 
     posterHeight = poster.getHeight(); 
     Log.d("parallax", "gridHeight: " + gridHeight + " - toolbar: " + toolbarHeight + " - poster: " + posterHeight); 
    } 
    if (!docked && metrics > posterHeight - toolbarHeight) 
    { 
     docked = true; 
     toolbar.setBackgroundColor(0xff000000); 
    } 
    if (docked && metrics < posterHeight - toolbarHeight) 
    { 
     docked = false; 
     toolbar.setBackgroundColor(0x00000000); 
    } 

    if (metrics < 0) 
     resize = 0; 
    else if (metrics > posterHeight - toolbarHeight) 
     resize = posterHeight - toolbarHeight; 
    else 
     resize = metrics; 

    header.setTranslationY(-resize); 
    grid.setTranslationY(-resize); 
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) grid.getLayoutParams(); 
    params.height = gridHeight + resize; 
    grid.setLayoutParams(params); 
} 
} 

и мой макет:

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<android.support.v7.widget.Toolbar 
    android:id="@+id/toolbar_actionbar" 
    android:background="@null" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:elevation="5dp" /> 

<LinearLayout 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 

<LinearLayout 
    android:id="@+id/header" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:elevation="0dp"> 

     <ImageView 
      android:id="@+id/poster" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:scaleType="centerCrop" 
      android:adjustViewBounds="true" 
      android:src="@drawable/jpeg"/> 
     <TextView 
      android:id="@+id/title" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:text="SerieKids" 
      android:textSize="20dp" 
      android:textColor="#ffffff" 
      android:background="#000000" 
      android:paddingStart="100dp"/> 
</LinearLayout> 

<android.support.v7.widget.RecyclerView 
    android:id="@+id/list" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#000000"/> 
</LinearLayout> 
</RelativeLayout> 

И, наконец, как я использую мера()

if (gridHeight == -1) 
{ 
    toolbar.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 
    poster.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 
    grid.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 

    gridHeight = grid.getMeasuredHeight(); 
    toolbarHeight = toolbar.getMeasuredHeight(); 
    posterHeight = poster.getMeasuredHeight(); 
    Log.d("parallax", "gridHeight: " + gridHeight + " - toolbar: " + toolbarHeight + " - poster: " + posterHeight); 
} 
+0

вы пробовали вместо сохранения метрики просто сохранить Y прокрутки и вызвать 'scrollTo'? Ваш onScrollListener должен позаботиться об остальном, я думаю. –

+0

На самом деле да, это был мой первый подход к восстановлению штата, но RecyclerView не работает именно так. - Он не принимает прокрутку в определенную позицию - да, это в руководстве, но это создаст исключение. - LayoutManager уже сохраняет позицию, используя свой собственный .onSaveInstanceState() и .onRestoreInstanceState И после всего .. даже если бы я мог .. разве я не получал бы ту же проблему? пытаться переместить вещи перед рендерингом или IDK? –

+0

Вы пытались запустить эту рутину на postDelayed и посмотреть, что произойдет? –

ответ

1

Добавьте onGlobalLayoutListener в ваш RecyclerView. Таким образом, вы убедитесь, что ваша программа parallax вызывается только после того, как вы просмотрели ее. Также убедитесь, что вы отменили регистрацию globalLayout, иначе он будет вызываться каждый раз, когда вы нарисуете свое представление (, если вы используете его для управления изменениями вращения, тогда нет необходимости удалять слушателя, я думаю. Таким образом, он всегда будет называться когда вы вращаетесь, потому что макет будет нарисован снова).

Пример того, как зарегистрировать и разрегистрировать макет слушателя:

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
       @Override 
       public void onGlobalLayout() { 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
         view.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
        } else { 
         view.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        } 
        //your parallax routine here 
       } 
      }); 
+0

На самом деле я даже не удаляю его. Вместо этого я удалил parallax() из onScrollListener. Итак, теперь он обновляет только «метрики», тогда мой globalLayoutListener запускает parallax(). –

+0

Это тоже работает :) Я также сделал эффект параллакса для recyclerView. Если вы хотите проверить это, https://github.com/kanytu/android-parallax-recyclerview У вас хороший день :) –

Смежные вопросы