android - 隠す - setsupportactionbar




RecyclerView-最初のレイアウトパスをスキップするオフスクリーンアイテム (2)

setHasStableIds(true)チェックして、各ビューのIDを指定するためにgetItemId(int position)をオーバーライドする必要があるかどうかを確認します。それをしないと、後続のonBindViewholders()呼び出しはトリガーされず、ビューは更新されません

私は自分のアダプターの1つに問題があります。 私は次のようなグリッドで表示する画像の選択肢を持っています:

これは、1画面分のアイテムがあり、すべてが上手く表示されている場合にうまく機能します。 問題は、スクロールする項目がさらに多い場合に表示されます。 最初はさらにスクロールして項目を空白にし、 GridLayoutコンテナはそこにあり、画像を表示するコードは実行されますが、ここに示すように画面には表示されません。

バックアップをスクロールしてからもう一度スクロールし直すと、画像は正確に表示されます。

レイアウトをリフレッシュしたり、レンダラに何か変更があったことを伝える必要があるようですが、何もしていないようです。 私はrequestLayoutを呼び出してinvalidateしようとinvalidateが、問題を解決していないようです。 私はGlobalOnLayoutListenerも登録しましたが、これ以上はうまくいきませんでした。

関連するコードは次のとおりです。

これは私のonBindViewHolderメソッドからのものonBindViewHolder

final GridLayout grid = ((KKAlbumViewHolder) holder).mGridLayout;
grid.removeAllViews();
int width = grid.getWidth();
if(width > 0) {
    albumHolder.setPreviewImages(posts);
}else {
    albumHolder.itemView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    albumHolder.itemView.removeOnLayoutChangeListener(this);
                    albumHolder.setPreviewImages(posts);
                    albumHolder.mGridLayout.invalidate();
                }
    });
}

これは私がイメージをレイアウトするのに使う方法です。 基本的には、不規則なグリッド内に画像を配置するので、長い画像や大きい画像がある場合、その画像は空き領域に応じて完全な行または完全な列を取得しようとします。 なぜなら、私はparamの幅と高さを設定しているので、ピカソは.fit()メソッドについて不平を言っていません。

public void setPreviewImages(ArrayList<KKPost> posts) {
        Picasso picasso = Picasso.with(itemView.getContext());

        int space = 0;
        int tl = 1 << 0;
        int tr = 1 << 1;
        int bl = 1 << 2;
        int br = 1 << 3;
        int lCol = tl | bl;
        int rCol = tr | br;
        int tRow = tl | tr;
        int bRow = bl | br;
        int full = lCol | rCol;
        boolean hasLongImage = false;
        for(KKPost post : posts) {
            if(space == full){
                break;
            }

            int margin = 2;

            ImageView view = new ImageView(itemView.getContext());
            GridLayout.LayoutParams param = new GridLayout.LayoutParams();
            view.setBackgroundColor(Color.LTGRAY);
            if(posts.size() < 4){
                param.columnSpec = GridLayout.spec(0, 2);
                param.rowSpec = GridLayout.spec(0, 2);
                param.width = mGridLayout.getWidth();
                param.height = mGridLayout.getHeight();
                mGridLayout.addView(view, param);
                picasso.load(post.url).fit().centerCrop().into(view);
                break;
            }

            if (post.aspectRatio >= 1.2 && !hasLongImage) {
                //landscape
                if((space & tRow) == 0){
                    param.rowSpec = GridLayout.spec(0, 1);
                    param.columnSpec = GridLayout.spec(0, 2);
                    param.height = mGridLayout.getHeight()/2;
                    param.width = mGridLayout.getWidth();
                    param.bottomMargin = margin;
                    space |= tRow;
                    mGridLayout.addView(view, param);
                    picasso.load(post.url).fit().centerCrop().into(view);
                    hasLongImage = true;
                    continue;
                }
                if((space & bRow) == 0){
                    param.rowSpec = GridLayout.spec(1, 1);
                    param.columnSpec = GridLayout.spec(0, 2);
                    param.height = mGridLayout.getHeight()/2;
                    param.width = mGridLayout.getWidth();
                    param.topMargin = margin;
                    space |= bRow;
                    mGridLayout.addView(view, param);
                    picasso.load(post.url).fit().centerCrop().into(view);
                    hasLongImage = true;
                    continue;
                }
            } else if (post.aspectRatio <= 0.8 && post.aspectRatio > 0 && !hasLongImage) {
                //portrait
                if((space & lCol) == 0){
                    param.columnSpec = GridLayout.spec(0, 1);
                    param.rowSpec = GridLayout.spec(0, 2);
                    param.height = mGridLayout.getHeight();
                    param.width = mGridLayout.getWidth()/2;
                    param.rightMargin = margin;
                    space |=  lCol;
                    mGridLayout.addView(view, param);
                    picasso.load(post.url).fit().centerCrop().into(view);
                    hasLongImage = true;
                    continue;
                }
                if((space & rCol) == 0){
                    param.columnSpec = GridLayout.spec(1, 1);
                    param.rowSpec = GridLayout.spec(0, 2);
                    param.height = mGridLayout.getHeight();
                    param.width = mGridLayout.getWidth()/2;
                    param.leftMargin = margin;
                    space |= rCol;
                    mGridLayout.addView(view, param);
                    picasso.load(post.url).fit().centerCrop().into(view);
                    hasLongImage = true;
                    continue;
                }
            }
            //square or no space or unknown
            if((space & tl) == 0){
                param.columnSpec = GridLayout.spec(0,1);
                param.rowSpec = GridLayout.spec(0,1);
                space |= tl;
                param.bottomMargin = margin;
                param.rightMargin = margin;
            }else
            if((space & tr) == 0) {
                param.columnSpec = GridLayout.spec(1,1);
                param.rowSpec = GridLayout.spec(0,1);
                space |= tr;
                param.bottomMargin = margin;
                param.leftMargin = margin;
            }else
            if((space & bl) == 0){
                param.columnSpec = GridLayout.spec(0,1);
                param.rowSpec = GridLayout.spec(1,1);
                space |= bl;
                param.rightMargin = margin;
                param.topMargin = margin;
            }else
            if((space & br) == 0){
                param.columnSpec = GridLayout.spec(1,1);
                param.rowSpec = GridLayout.spec(1,1);
                space |= br;
                param.leftMargin = margin;
                param.topMargin = margin;
            }
            param.height = mGridLayout.getHeight()/2;
            param.width = mGridLayout.getWidth()/2;
            mGridLayout.addView(view, param);
            picasso.load(post.url).fit().centerCrop().into(view);
        }
    }
}

最初に表示されていない項目の最初のレンダリングパスでこれがスキップされるのはなぜですか?

編集:私はリファクタリングを少ししたので、新しいものを削除/作成するのではなく、イメージビューを再利用して、それらのアイテムに追加されたビューがonLayoutChangeコールバックを取得しないことを知りました。 他のすべてのアイテムはonLayoutChangeコールバックを取得し、前と同じように、最初にコールを取得しないアイテムは、スクロールしてスクロールした後に取得します。 見る:

view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    view.removeOnLayoutChangeListener(this);
                    picasso.load(post.url).into(view);
                }
            });

編集:11月15日

ビューアのレイアウトのxmlは次のとおりです

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    android:id="@+id/album_card_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    card_view:cardCornerRadius="@dimen/feed_card_corner_radius"
    card_view:cardElevation="@dimen/cardview_default_elevation"
    card_view:cardMaxElevation="@dimen/cardview_default_elevation"
    card_view:cardUseCompatPadding="true"
    xmlns:autofit="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto">

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

        <android.support.percent.PercentRelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/percent_layout">

            <GridLayout
                android:background="@color/white"
                android:id="@+id/preview_grid_layout"
                android:columnCount="2"
                android:rowCount="2"
                android:alignmentMode="alignBounds"
                android:layout_height="0dp"
                android:layout_width="0dp"
                app:layout_widthPercent="100%"
                app:layout_aspectRatio="100%">

            </GridLayout>

        </android.support.percent.PercentRelativeLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="@dimen/card_padding_4dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/album_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                tools:text="Family Photos"/>

         </LinearLayout>

    </LinearLayout>

</android.support.v7.widget.CardView>

おそらくリストを作成しようとしているので、 RecyclerViewクラスの使用を検討する必要があります。 この方法で、LayoutManagerを利用して写真をより簡単にレイアウトすることができます。 これは、レイアウトが標準のグリッド(幅と高さが一定である)ではないため、より良いことがあります。 興味深い例として、カスタムLayoutManagerを見てみましょう。





gridlayoutmanager