Я пытаюсь закодировать свой собственный эффект параллакса, используя вид ресайклера. В настоящий момент это очень хорошо работает ... пока я не изменю ориентацию устройства.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);
}
вы пробовали вместо сохранения метрики просто сохранить Y прокрутки и вызвать 'scrollTo'? Ваш onScrollListener должен позаботиться об остальном, я думаю. –
На самом деле да, это был мой первый подход к восстановлению штата, но RecyclerView не работает именно так. - Он не принимает прокрутку в определенную позицию - да, это в руководстве, но это создаст исключение. - LayoutManager уже сохраняет позицию, используя свой собственный .onSaveInstanceState() и .onRestoreInstanceState И после всего .. даже если бы я мог .. разве я не получал бы ту же проблему? пытаться переместить вещи перед рендерингом или IDK? –
Вы пытались запустить эту рутину на postDelayed и посмотреть, что произойдет? –