22

私はAmazon Fire TVで開発しています。

これは TV アプリ (タッチなし) であるため、移動できるようにするには、行のレイアウト内にフォーカス可能要素が必要です。

私は、Recyclerview画像、テキスト、およびフォーカス可能なものを非常にシンプルにしています。上または下に押すと、すべてが正しくスクロールされますが、スクロールが追いつかないほど速くナビゲートすると、新しいビューホルダー (オフスクリーン) が作成され、UI が遅れることに気付きました。

作成番号を含むアクティビティを作成しました。ゆっくりスクロールすると最高のクリエイション # は 10 ですが、速くスクロールするとクリエイション番号が 60 のカードが 1 秒で表示されます。これにより、膨大な遅延が発生し、アプリケーションは多くのフレームをドロップします。私のアプローチは完全に間違っていますか?

以下のコードを使用して、これをテストします。

/**
 * Created by sylversphere on 15-04-15.
 */
public class LandfillActivity extends Activity{

private Context context;

private static int ticketNumber;
private static int getTicket(){
    ticketNumber ++;
    return ticketNumber;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    setContentView(R.layout.landfill_activity);
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    GridLayoutManager glm = new GridLayoutManager(context, 2);
    recyclerView.setLayoutManager(glm);
    SickAdapter sickAdapter = new SickAdapter();
    recyclerView.setAdapter(sickAdapter);
}

public class SickViewHolder extends RecyclerView.ViewHolder{
    TextView ticketDisplayer;
    public ImageView imageView;
    public SickViewHolder(View itemView) {
        super(itemView);
        ticketDisplayer = (TextView) itemView.findViewById(R.id.ticketDisplayer);
        imageView = (ImageView) itemView.findViewById(R.id.imageView);

        itemView.findViewById(R.id.focus_glass).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                context.startActivity(new Intent(context, LouisVuittonActivity.class));
            }
        });
    }
    public void setTicket(int value){
        ticketDisplayer.setText(""+value);
    }
}

public class SickAdapter extends RecyclerView.Adapter<SickViewHolder>{

    @Override
    public SickViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        SickViewHolder svh = new SickViewHolder(getLayoutInflater().inflate(R.layout.one_row_element, null));
        svh.setTicket(getTicket());
        return svh;
    }

    @Override
    public void onBindViewHolder(SickViewHolder holder, int position) {
        String[] image_url_array = getResources().getStringArray(R.array.test_image_urls);
        Picasso.with(context).load(image_url_array[position % image_url_array.length] ).fit().centerCrop().into(holder.imageView);
    }

    @Override
    public int getItemCount() {
        return 100000;
    }
}
}

one_row_element.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop"
            android:src="@mipmap/sick_view_row_bg" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left|center_vertical"
            android:layout_marginLeft="15dp"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/virusTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Creation #"
                android:textColor="#fff"
                android:textSize="40sp" />
            <TextView
                android:id="@+id/ticketDisplayer"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="1"
                android:textColor="#fff"
                android:textSize="40sp" />
        </LinearLayout>
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/focus_glass"
            android:background="@drawable/subtle_focus_glass"
            android:focusable="true"
            android:focusableInTouchMode="true"/>
    </FrameLayout>
</FrameLayout>

test_image_urls.xml (私が所有していない URL)

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="test_image_urls"
    formatted="false">
    <item>http://farm4.static.flickr.com/3175/2737866473_7958dc8760.jpg</item>
    <item>http://farm4.static.flickr.com/3276/2875184020_9944005d0d.jpg</item>
    <item>http://farm3.static.flickr.com/2531/4094333885_e8462a8338.jpg</item>
    <item>http://farm4.static.flickr.com/3289/2809605169_8efe2b8f27.jpg</item>
    <item>http://2.bp.blogspot.com/_SrRTF97Kbfo/SUqT9y-qTVI/AAAAAAAABmg/saRXhruwS6M/s400/bARADEI.jpg</item>
    <item>http://fortunaweb.com.ar/wp-content/uploads/2009/10/Caroline-Atkinson-FMI.jpg</item>
    <item>http://farm4.static.flickr.com/3488/4051378654_238ca94313.jpg</item>
    <item>http://farm4.static.flickr.com/3368/3198142470_6eb0be5f32.jpg</item>
    <item>http://www.powercai.net/Photo/UploadPhotos/200503/20050307172201492.jpg</item>
    <item>http://www.web07.cn/uploads/Photo/c101122/12Z3Y54RZ-22027.jpg</item>
    <item>http://www.mitravel.com.tw/html/asia/2011/Palau-4/index_clip_image002_0000.jpg</item>
    <item>http://news.xinhuanet.com/mil/2007-05/19/xinsrc_36205041914150623191153.jpg</item>
    <item>http://ib.berkeley.edu/labs/koehl/images/hannah.jpg</item>
    <item>http://down.tutu001.com/d/file/20110307/ef7937c2b70bfc2da539eea9df_560.jpg</item>
    <item>http://farm3.static.flickr.com/2278/2300491905_5272f77e56.jpg</item>
    <item>http://www.pic35.com/uploads/allimg/100526/1-100526224U1.jpg</item>
    <item>http://img.99118.com/Big2/1024768/20101211/1700013.jpg</item>
    <item>http://farm1.static.flickr.com/45/139488995_bd06578562.jpg</item>
</string-array>
</resources>

微妙な焦点

    <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:drawable="@color/glass_focus"/>
    <item android:drawable="@color/glass_normal"/>
</selector>

glass_normal#9000

glass_focus#0000

4

5 に答える 5

20

プール内のリサイクルされたビューの最大数を増やしてみてください。

recyclerView.getRecycledViewPool().setMaxRecycledViews(50);

50 は任意の数値です。これより高くしたり低くしたりして、何が起こるかを確認してください。

RecyclerView は、一時的な状態を持つビューの再利用を回避しようとします。そのため、ビューがすぐに無効化されたり、アニメーション化されたりすると、すぐに再利用されない可能性があります。

同様に、小さなビューが多数ある場合、デフォルトのプール サイズが処理できるよりも多くのビューが画面に表示される可能性があります (グリッドのようなレイアウトでより一般的です)。

于 2015-04-28T01:07:08.807 に答える
3

ピカソはあなたを妨害していますが、独自のメカニズムを構築するために提案された解決策は進むべき道ではありません.

Picasso はここ 1 年ほどで遅れをとってしまいましたが、今日ではGoogle GlideFacebook Frescoの形ではるかに優れた代替手段があり、RecyclerView との連携を改善するためのアップデートを特別にリリースし、多くのアプリケーションでの読み込み、キャッシュ、保存がより高速かつ効率的であることが証明されています。次のようなオンラインで利用できるテスト:

お役に立てば幸いです。幸運を。

于 2015-04-27T06:33:04.573 に答える
2

コメンテーターが指摘したように、ピカソからの保留中の応答があなたを妨げている可能性があります. その場合はImageView、以下のメソッドを拡張してオーバーライドすることで解決できます。試す価値はあると思います。

@Override
protected void onDetachedFromWindow() {
    Picasso.with(context).cancelRequest(this);
    super.onDetachedFromWindow();
}

アップデート:

これは正しい方法ではないことが判明しました。リクエストをキャンセルしたい人はonViewRecycled()、以下のコメントで指摘されているように、コールバックでキャンセルする必要があります。

于 2015-04-21T15:55:52.487 に答える
-2

簡単なハックを探している他の人は、これを実行してください。これは、膨張して選択されるまで選択を遅らせます。方法はわかりませんが、機能します。onFocusSearchFailed で null を返すだけです。

 /**
 * Created by sylversphere on 15-04-22.
 */
public class SomeGridLayoutManager extends GridLayoutManager{

    private final Context context;

    public SomeGridLayoutManager(Context context, int spanCount) {
        super(context, spanCount);
        this.context = context;
    }

    public SomeGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);
        this.context = context;
    }

    @Override
    public View onFocusSearchFailed(View focused, int focusDirection, RecyclerView.Recycler recycler, RecyclerView.State state) {
        return null;
    }
}
于 2015-05-20T21:27:53.967 に答える