スクロールに問題があります。つまり、scroolは高速ですが、スクロールが終了する前に遅れているように見えます。ここでRecyclerViewを定義します。
RecyclerView recyclerView=fragment.getRecyclerView();
LinearLayoutManager layoutManager = new LinearLayoutManager(fragment.getActivity(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(fragment.getActivity(), LinearLayoutManager.VERTICAL));
ArrayList<InstaPostModel> rowListItems=getInstaPostListSample();
InstaPostAdapter rcAdapter = new InstaPostAdapter(rowListItems);
recyclerView.setAdapter(rcAdapter);
そしてここにonBindViewHolder
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final InstaPostModel p = items.get(position);
context = holder.itemView.getContext();
Glide.with(context).load(R.mipmap.mee_small).into(holder.userPhoto);
Glide.with(context).load(R.drawable.post_image).into(holder.photo_content);
Glide.with(context).load(R.mipmap.love_gray_icon).into(holder.bt_like);
Glide.with(context).load(R.mipmap.comment_icon).into(holder.bt_comment);
Glide.with(context).load(R.mipmap.share_icon).into(holder.bt_share);
holder.userNameTextView.setText(p.getPosterUserName());
holder.postContent.setText(p.getText());
holder.post_date.setReferenceTime(p.getDate().getTime());
}
そしてここRecyclerView.xml
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.RecyclerView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/qatar_now_posts_recycler_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:scrollbars="none"
tools:context=".uis.fragments.home.QatarNowFragment"
/>
編集また、同じフラグメントに下部のナビゲーションバーがあり、スクロールすると表示されます
編集2ここにビデオがあります リンク ラグを示しています
私はすべての解決策を試しましたが、誰も助けてくれませんでした。すべてのコードを追加しました。何か助けてください。
コードに問題はありませんでした。まだ以下の点を考慮する必要があります。
(1)APIから取得しているimageのサイズが大きすぎるであるとどうなる可能性がありますか。 APIのサイズを確認し、最大200kb削減します。 (100〜150 kbでも十分です)。
(2)あなたキャッシュを無効にしないでください画像をキャッシュに保存することでユーザーエクスペリエンスを向上させ、次回はURLではなくキャッシュでロードします。
(3)あなた今すぐAndroidで利用できる単純な波及効果のためにmaterial-ripple
ライブラリを使用する必要はありません。この属性をImageView
Android:background="?attr/selectableItemBackground"
(4)一度にロードするアイテムの数を確認します。一度に多くのアイテムをロードしないでください。 アーキテクチャコンポーネントページングライブラリ を参照してください
(5)love_gray_icon
のようなリソースのサイズも確認してください。最大だと思います70 * 7。それよりも大きい場合は、サイズを変更する必要があります。 一度に複数の画像のサイズを変更する 。また、使用前に画像を圧縮すると、画像サイズが最大80%減少します。サイズ変更後、 画像を圧縮 。
(6)Glideは手入れの行き届いたライブラリであるため、onViewRecycled
は冗長です。
最後に、コードを少し修正します。
private void loadImage(ImageView iv, String url) {
Glide.with(iv.getContext()).load(url).thumbnail(0.5f).into(iv);
}
private void loadImage(ImageView iv, int resId) {
Glide.with(iv.getContext()).load(resId).thumbnail(0.5f).into(iv);
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final InstaPostModel p = items.get(position);
loadImage(holder.userPhoto, Urls.BASE_URI + p.getUserPhotoUrl());
loadImage(holder.photo_content, Urls.BASE_URI + p.getPostPhotoUrl());
loadImage(holder.bt_like, R.mipmap.love_gray_icon);
loadImage(holder.bt_comment, R.mipmap.comment_icon);
loadImage(holder.bt_share, R.mipmap.share_icon);
holder.userNameTextView.setText(p.getPosterUserName());
holder.postContent.setText(p.getText());
holder.post_date.setReferenceTime(p.getDate().getTime());
}
画像が大きすぎることが原因である可能性があります
グライドのようにサイズを変更できます
Glide.with(context)
.load(imgUrl)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.error(placeholder)
.placeholder(placeholder)
.dontTransform()
.override(200,200)
.into(imageView);
次のようにコードを最適化できます。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final InstaPostModel p = items.get(position);
context = holder.itemView.getContext();
setImage(holder.userPhoto, p.getUserPhotoUrl());
setImage(holder.photo_content, p.getPostPhotoUrl());
setImage(holder.bt_like, R.mipmap.love_gray_icon);
holder.userNameTextView.setText(p.getPosterUserName());
holder.postContent.setText(p.getText());
holder.post_date.setReferenceTime(p.getDate().getTime());
}
private void setImage(ImageView iv, String url)
{
Glide.with(context)
.load(Urls.BASE_URI +url).thumbnail(0.5f)
.apply(new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true).dontAnimate()
)
.into(iv);
}
private void setImage(ImageView iv, int resource)
{
Glide.with(context)
.load(resource).thumbnail(0.5f)
.apply(new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true).dontAnimate()
)
.into(iv);
}
レンダリング中の負荷は確実に減少します。list.get(position)呼び出しは毎回メモリにコストがかかるため、アダプタをトラバースする場合にのみ変数を使用するようにしてください。
スクロールの問題は、バインド中に画像をリロードしていることが原因である可能性があると思います。写真の読み込み中、そしてもちろんページネーション中にキャッシュを使用できます。
私はあなたにいくつかの改善提案があります。
Android:src
として設定します。onViewRecycled
関数を削除します。Context
を使用してアダプターを初期化します。 onBindViewHodler
内で毎回取得する必要はありません。RequestOption
関数で毎回onBindViewHolder
を初期化する必要はありません。一度初期化して、各Glideイメージローダーで使用するだけです。DiskCacheStrategy.ALL
を使用して画像をキャッシュし、アプリケーションを開いたりRecyclerView
を読み込んだりするたびに画像が読み込まれないようにします。したがって、最終的なアダプタは次のようになります。
public class InstaPostAdapter
extends RecyclerView.Adapter<InstaPostAdapter.ViewHolder> {
private List<InstaPostModel> items = new ArrayList<>();
Context context;
// Initialize the context once, use it everywhere
public InstaPostAdapter(List<InstaPostModel> items, Context context) {
this.items = items;
this.context = context;
}
@Override
public InstaPostAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.insta_post_list_item, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final InstaPostModel p = items.get(position);
RequestOptions requestOptions = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(context)
.load(Urls.BASE_URI + items.get(position).getUserPhotoUrl()).thumbnail(0.5f)
.apply(requestOptions)
.into(holder.userPhoto);
Glide.with(context)
.load(Urls.BASE_URI + items.get(position).getPostPhotoUrl()).thumbnail(0.5f)
.apply(requestOptions)
.into(holder.photo_content);
// Removed the like, comment, share images which should be set from layout.
holder.userNameTextView.setText(p.getPosterUserName());
holder.postContent.setText(p.getText());
holder.post_date.setReferenceTime(p.getDate().getTime());
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return items.size();
}
@Override
public long getItemId(int position) {
return position;
}
public void add(InstaPostModel post, int i) {
items.add(post);
notifyItemInserted(i);
}
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public ImageView userPhoto;
public TextView userNameTextView;
public ImageView bt_more;
public ImageView photo_content;
public ImageView bt_like;
public ImageView bt_comment;
public ImageView bt_share;
public TextView postContent;
public RelativeTimeTextView post_date;
public ViewHolder(View v) {
super(v);
userPhoto = v.findViewById(R.id.insta_user_photo);
userNameTextView = v.findViewById(R.id.insta_user_name);
bt_more = v.findViewById(R.id.insta_bt_more);
photo_content = v.findViewById(R.id.insta_photo_content);
bt_like = v.findViewById(R.id.insta_bt_like);
bt_comment = v.findViewById(R.id.insta_bt_comment);
bt_share = v.findViewById(R.id.insta_bt_share);
postContent = v.findViewById(R.id.insta_post_content);
post_date = v.findViewById(R.id.insta_post_date);
setClickListener();
}
private void setClickListener() {
bt_more.setOnClickListener(view -> {
PopupMenu popupMenu = new PopupMenu(context, view);
popupMenu.setOnMenuItemClickListener(item -> {
Snackbar.make(view, item.getTitle() + " Clicked", Snackbar.LENGTH_SHORT).show();
return true;
});
popupMenu.inflate(R.menu.menu_feed_popup);
popupMenu.show();
});
bt_like.setOnClickListener(view -> Snackbar.make(view, "Like Clicked", Snackbar.LENGTH_SHORT).show());
bt_comment.setOnClickListener(view -> Snackbar.make(view, "Comment Clicked", Snackbar.LENGTH_SHORT).show());
bt_share.setOnClickListener(view -> Snackbar.make(view, "Share Clicked", Snackbar.LENGTH_SHORT).show());
}
}
}
Flickrの画像検索についても同様のプロジェクトが行われていると思います。 ここGithubのプロジェクト を見つけるかもしれません。
お役に立てば幸いです。
recyclerviewのアイテムが同じサイズの場合は、次のことを試すことができます。recyclerview.setHasFixedSize(true);