#android #android-recyclerview
#Android #android-recyclerview
Вопрос:
Я пытался исправить медленную прокрутку в приложении, похожем на Twitter, с помощью RecyclerView, используя предложения из this [link] [1], и у меня возникли проблемы с #7 «setHasStableIds (true)». Когда я не переопределяю getItemId(), я получаю только около 6 элементов в моем RecyclerView из 30. Когда я переопределяю его и возвращаю position или tweetStatusID для функции, он по-прежнему отстает, как когда я не использовал setHasStableIds (true) для своего адаптера.
ОБНОВЛЕНО: я добавил несколько асинхронных задач, которые улучшили мою скорость, но все еще медленно, мне было любопытно, можно ли внести какие-либо дополнительные улучшения или можно ли предварительно загрузить больше просмотров, чтобы при быстрой прокрутке было готово больше.
MyFeed onCreate():
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
final RecyclerView recyclerView = findViewById(R.id.rv_feed);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
DatabaseReference databaseReference;
// Create new Twitter configuration
ConfigurationBuilder cb = new ConfigurationBuilder();
// Create Twitter instance for retweeting
TwitterFactory tf = new TwitterFactory(cb.build());
twitter = tf.getInstance();
authTokenToken = getIntent().getStringExtra("AUTH_TOKEN_TOKEN");
authTokenSecret = getIntent().getStringExtra("AUTH_TOKEN_SECRET");
// Firebase Auth
mAuth = FirebaseAuth.getInstance();
dbFeedPath = getResources().getString(R.string.isu_feed);
databaseReference = FirebaseDatabase.getInstance().getReference(dbFeedPath);
databaseReference.addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(@NonNull final DataSnapshot dataSnapshot)
{
AsyncTask.execute(new Runnable()
{
@Override
public void run()
{
listFeedList.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren())
{
TweetData tweetData = postSnapshot.getValue(TweetData.class);
if ((tweetData != null) amp;amp; (!tweetData.tweetText.equals("")))
{
TweetData listTweetData = new TweetData(tweetData);
listFeedList.add(listTweetData);
}
}
}
});
mAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
{
}
});
mAdapter = new TweetListAdapterFeed(listFeedList, this.getApplicationContext(), new ClickListener()
{
});
mAdapter.setHasStableIds(true);
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(mAdapter);
Адаптер:
public class TweetListAdapterFeed extends RecyclerView.Adapter<TweetListAdapterFeed.ViewHolder>
{
private static List<TweetData> mData;
private static Context context;
public static FirebaseAuth mAuth;
private static String dbFeedPath;
private static ClickListener clickListener;
ConfigurationBuilder cb;
TwitterFactory tf;
Twitter twitter;
public TweetListAdapterFeed(@SuppressWarnings("SameParameterValue") List<TweetData> mData,
Context context, ClickListener clickListener)
{
TweetListAdapterFeed.mData = mData;
TweetListAdapterFeed.context = context;
TweetListAdapterFeed.clickListener = clickListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
{
dbFeedPath = context.getString(R.string.isu_feed);
ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.feed_list_item, viewGroup,
false), clickListener);
statusAsyncTask = new StatusAsyncTask(this, viewHolder, i);
mediaAsyncTaskFeed = new MediaAsyncTaskFeed(this, viewHolder);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, final int i)
{
// Update Like and Retweet Count via AsyncTask
statusAsyncTask.execute(mData.get(i).getTweetStatusID());
// Tweet Media
if (!mData.get(i).getTweetPic1().equals(""))
{
viewHolder.photo1.setVisibility(View.VISIBLE);
viewHolder.photo1.setImageResource(R.drawable.loading_image);
mediaAsyncTaskFeed.execute(mData.get(i).getTweetPic1());
}
else
{
viewHolder.photo1.setVisibility(View.GONE);
}
// Twitter Profile Image
Picasso.get().load(mData.get(i).getProfileImage()).fit().into(viewHolder.profileImage);
// Twitter Name
viewHolder.twitterName.setText(mData.get(i).getTwitterName());
// Twitter Handle
String tString = context.getString(R.string.AtSymbol) mData.get(i).getTwitterHandle();
viewHolder.twitterHandle.setText(tString);
// Tweet Time, converted to Time since Tweet was posted
String timeAgo = convertDateToTimeAgo(mData.get(i).getTweetTime());
viewHolder.tweetDate.setText(timeAgo);
// Tweet Text
viewHolder.tweetText.setText(mData.get(i).getTweetText());
// Retweeted By
if (!mData.get(i).getRetweetedBy().equals(""))
{
// Tweet was a Retweet
viewHolder.retweetedBy.setText(mData.get(i).getRetweetedBy());
viewHolder.retweetedBy.setVisibility(View.VISIBLE);
viewHolder.imageRetweetedBy.setVisibility(View.VISIBLE);
}
else
{
// Tweet was original
viewHolder.retweetedBy.setText("");
viewHolder.retweetedBy.setVisibility(View.GONE);
viewHolder.imageRetweetedBy.setVisibility(View.GONE);
}
}
/*
@Override
public long getItemId(int position)
{
return position; //TweetListAdapterFeed.mData.get(position).getTweetStatusID();
}
*/
Комментарии:
1. Вы вызываете
StrictMode.ThreadPolicy.Builder().permitAll().build()
, который специально позволяет вам выполнять сверхмедленные действия в основном потоке. Конечно, это будет отставать, если вы это сделаете.2. Вы использовали
AsyncTasks
в 2020 году, а Java не Kotlin?3. @IgorGanapolsky Я новичок, это мое первое приложение, что вы предлагаете вместо асинхронных задач? Кроме того, я родом из мира C , поэтому Java было легко подобрать, со временем изучу Kotlin.
4. @BiCURE Пожалуйста, посмотрите на сопрограммы Kotlin для асинхронного программирования: developer.android.com/kotlin/coroutines