gpt4 book ai didi

Android ListView 每次滚动都会滞后,即使使用 ViewHolder

转载 作者:搜寻专家 更新时间:2023-11-01 08:39:48 28 4
gpt4 key购买 nike

我想提供一些背景信息:我目前参与帮助开发的应用程序是一家公司已经为 IOS 和 Android 开发的应用程序,但 Android 开发人员没有交付预期的结果(主要是性能方面),所以领导给了我代码,看能不能搞定。鉴于我尝试改进它的代码,现在,该应用程序是一个有点像 Instagram 的图片共享应用程序,它使用无休止的滚动列表,该应用程序的问题是每次我滚动一点,应用程序都会延迟或卡住一秒钟,然后加载新行。

ListView 在任何时候都只有一行可见。

我尝试了什么?

适配器没有使用 ViewHolder 模式,所以我尝试实现它。

程序员在 getView 方法上定义了很多点击监听器,所以我删除了它们。

仍然,每次我滚动时(新行出现,因为在任何时候都只有一个可见行)它滞后。这里是否还有任何其他明显的问题可能是原因?

另一方面,在这个 View 上有很多 overdraw ,所以,也许它影响了 ListView 的性能?如果是,请告诉我,我会发布 XML 部分。

这是我改编的代码:

public class SomeFragment extends Fragment  implements SwipeRefreshLayout.OnRefreshListener {

// declaration and constructors.....

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {

//initialization......
//setting variables.......
//getting views.....
listview = (ListView)rootView.findViewById(R.id.listview);

listview.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int threshold = 1;
int count = listview.getCount();

if (scrollState == SCROLL_STATE_IDLE) {
if (listview.getLastVisiblePosition() >= count - threshold) {
int position = listview.getLastVisiblePosition();
if (!loading) {
loading = true;
listview.addFooterView(footerView, null, false);
currentVal = position + 1;
LoadMoreStuffAsyncTask loadMoreStuffAsyncTask = new LoadMoreStuffAsyncTask();
loadMoreStuffAsyncTask.execute();
}

}
}
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int topRowVerticalPosition = (listview == null || listview.getChildCount() == 0) ? 0 : listview.getChildAt(0).getTop();
swipeRefreshLayout.setEnabled(firstVisibleItem == 0 && topRowVerticalPosition >= 0);
}
});
LoadStuffAsyncTask loadStuffAsyncTask=new LoadStuffAsyncTask();
loadStuffAsyncTask.execute();

}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity, container, false);
swipeRefreshLayout = (SwipeRefreshLayout)rootView.findViewById(R.id.swipe);
swipeRefreshLayout.setOnRefreshListener(SomeFragment.this);

return rootView;
}


private void LoadStuff () {
list=null;
ParseQuery<ParseObject> query = null;
query = ParseQuery.getQuery("Objects");
query.orderByDescending("createdAt");
query.include("User");
query.setLimit(20);

try {
list = query.find();

} catch (ParseException e) {
e.printStackTrace();
}
}

private void LoadMoreStuff () {

List<ParseObject> moreList=null;
ParseQuery<ParseObject> query = null;
query = ParseQuery.getQuery("Objects");
query.orderByDescending("createdAt");
query.include("User");
query.setLimit(20);
query.setSkip(currentVal);

try {
moreList = query.find();
if(moreList!=null|| moreList.size()!=0){
for(int i =0;i<moreList.size();i++){
list.add(moreList.get(i));
}
}else{
loading=false;
}

} catch (ParseException e) {
e.printStackTrace();
loading=false;
}
}

@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
listAdapter.notifyDataSetChanged();
LoadStuffAsyncTask loadStuffAsyncTask=new LoadStuffAsyncTask();
loadStuffAsyncTask.execute();
}

class LoadMoreStuffAsyncTask extends AsyncTask<Void, Void, Void>{
private ProgressDialog pDialog;

@Override
protected Void doInBackground(Void... params) {
LoadMoreStuff();
return null;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
listAdapter.updateList(list);
listview.setAdapter(listAdapter);
loading=false;
listview.removeFooterView(footerView);
listview.setSelection(currentVal);

}
}

class LoadStuffAsyncTask extends AsyncTask<Void, Void, Void>{
private ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(activity);
pDialog.setMessage(activity.getString(R.string.loading));
pDialog.setCancelable(false);
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.show();
}


@Override
protected Void doInBackground(Void... params) {
LoadStuff();
return null;
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pDialog.dismiss();
swipeRefreshLayout.setRefreshing(false);
listAdapter = new CustomAdapter(activity,momentosGeneral);
listview.setAdapter(listAdapter);

}
}
}

这是适配器:

public class CustomAdapter extends BaseAdapter {

//declaration of variables.....

public CustomAdapter(ActionBarActivity activity, List<ParseObject> list) {

this.activity = activity;
this.list = list;
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return position;
}

@Override
public long getItemId(int position) {
return position;
}

private static class ViewHolder{
//holderfields......
}

@Override
public View getView(final int position, View v, ViewGroup parent) {
ViewHolder holder;
if (v == null) {
v = View.inflate(activity.getApplicationContext(), R.layout.customview, null);
holder = new ViewHolder();
holder.profilepicture = (CircularImageView) v.findViewById(R.id.profilepic);
holder.username = (TextView) v.findViewById(R.id.username);
holder.picture = (ParseImageView) v.findViewById(R.id.picture);
holder.container =(LinearLayout)v.findViewById(R.id.container);
holder.share=(LinearLayout)v.findViewById(R.id.share);
holder.comment= (TextView) v.findViewById(R.id.comment);
holder.likes= (TextView) v.findViewById(R.id.likes);
holder.publishDate =(TextView)v.findViewById(R.id.publisdate);
holder.liked = (ImageView)v.findViewById(R.id.liked);
v.setTag(holder);
}

holder = (ViewHolder)v.getTag();
CustomTypography customTypo = new CustomTypography(activity.getApplicationContext());
holder.username.setTypeface(customTypo.OpenSansSemibold());

if(list.get(position).getParseUser("User")!=null){
holder.username.setText(list.get(position).getParseUser("User").getString("name"));
profilePic = list.get(position).getParseUser("User").getParseFile("profilePic");

if (profilePic != null) {
try {
Drawable drawable = new BitmapDrawable(BitmapFactory.decodeByteArray(profilePic.getData(), 0, profilePic.getData().length));
holder.profilepicture.setImageDrawable(drawable);
holder.profilepicture.setDrawingCacheEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
}

}
else{

holder.username.setText("");
}

final ParseFile picture = list.get(position).getParseFile("picture");
if (picture != null) {
try {
Drawable drawable = new BitmapDrawable(BitmapFactory.decodeByteArray(picture.getData(), 0, picture.getData().length));
holder.picture.setImageDrawable(drawable);
holder.picture.setDrawingCacheEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
}
else{

}

holder.container.setLayoutParams(customLayoutParams);

holder.comment.setText(capitalizarPrimeraLetra(list.get(postiion).getString("Comment")));
holder.comment.setTypeface(customTypo.OpenSansRegular());

final int likes= list.get(position).getInt("Likes");
if(likes==0|| likes<0){
holder.likes.setText("");
}else{
holder.likes.setText(String.valueOf(likes));
}

holder.likes.setTypeface(customTypo.OpenSansLight());


holder.publishDate.setText(timeBetween(list.get(position).getCreatedAt()));

ParseQuery<ParseObject> query = ParseQuery.getQuery("LikedPictures");
query.whereEqualTo("picture", list.get(position));
query.whereEqualTo("user", currentUser);


query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> likelist, ParseException e) {

if (e == null) {
if (likelist.size() != 0) {
hasLiked = true;
holder.liked.setBackground(activity.getApplicationContext().getResources().getDrawable(R.drawable.like));
holder.likes.setTextColor(activity.getApplicationContext().getResources().getColor(R.color.red));
} else {
hasLiked = false;
}
} else {
hasLiked = false;
}

}
});
return v;
}
private String timeBetween(Date date){
String result="";
Date parsedPictureDate = null;
Date parsedCurrentDate=null;
Date today = new Date();
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
try {
parsedPictureDate= dateFormatLocal.parse(dateFormatGmt.format(date));
parsedCurrentDate=dateFormatLocal.parse(dateFormatGmt.format(hoy));
} catch (java.text.ParseException e) {
result="";
}

long milis=parsedCurrentDate.getTime()-parsedPictureDate.getTime();
final long MILISECS_PER_MINUTE=milis/(60 * 1000);
final long MILISECS_PER_HOUR=milis/(60 * 60 * 1000);
final long MILLSECS_PER_DAY=milis/(24 * 60 * 60 * 1000);


if(milis<60000){
result="Now";
}
if(milis>=60000&&milis<3600000){
result=MILISECS_PER_MINUTE+" min";

}
if(milis>=3600000&&milis<86400000){
result=MILISECS_PER_HOUR+" h";

}
if(milis>=86400000){
result=MILLSECS_PER_DAY+" d";
}
return result;
}

这是总是在 ListView 中填充的项目

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:background="@android:color/white"
android:paddingBottom="20dp"
android:layout_height="match_parent">


<LinearLayout

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

android:id="@+id/somelayout"
android:layout_weight="0.5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/margin_16dp_sw600"

android:layout_marginLeft="5dp"
android:paddingRight="@dimen/padding_16dp_sw600"
android:gravity="left"
android:layout_marginBottom="5dp">

<customImageView

android:layout_gravity="center"
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/profilepicture"
app:border_width="0dp"

/>

<TextView
android:layout_marginLeft="@dimen/margin_16dp_sw600"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/username"
android:textSize="14sp"
android:gravity="left"
android:singleLine="true"
android:minLines="1"
android:maxLines="1"
android:lines="1"
/>



</LinearLayout>

<LinearLayout

android:id="@+id/layoutTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
android:layout_weight="0.5"
android:layout_gravity="center" >
<TextView
android:gravity="right"
android:id="@+id/publishdate"
android:layout_marginRight="@dimen/margin_16dp_sw600"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"


/>
</LinearLayout>
</LinearLayout>

<LinearLayout
android:paddingLeft="5dp"

android:layout_width="wrap_content"
android:layout_height="wrap_content">


<LinearLayout
android:id="@+id/container"
android:layout_gravity="center"
android:background="@drawable/border"

android:layout_width="wrap_content"

android:layout_height="wrap_content"
>
<com.parse.ParseImageView

android:layout_margin="1dp"
android:layout_width="match_parent"
android:layout_height="match_parent"

android:id="@+id/picture" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>

<LinearLayout
android:id="@+id/layoutlikes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="left"
android:layout_weight="0.5"

android:layout_gravity="center" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/likes"
>
<TextView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/numlikes"
android:text="0"
android:textSize="14sp"
android:layout_margin="@dimen/margin_16dp_sw600"
/>
<ImageView
android:layout_gravity="center"
android:layout_marginRight="@dimen/margin_16dp_sw600"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/likepic"
android:background="@drawable/like_off"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/sharelayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
android:padding="10dp"
android:layout_weight="0.5"
android:layout_marginTop="@dimen/margin_16dp_sw600"
android:layout_gravity="center" >
<ImageView

android:layout_gravity="center"
android:layout_marginRight="@dimen/margin_16dp_sw600"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/sharepic"
android:background="@drawable/ellipsis"
/>
</LinearLayout>
</LinearLayout>
<View

android:layout_width="match_parent"
android:layout_height="@dimen/division_2dp_sw_600"
android:layout_margin="@dimen/margin_16dp_sw600"
android:background="@color/loading" />
<TextView

android:layout_gravity="left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/comment"

android:textSize= "14sp"

android:layout_marginLeft="@dimen/margin_16dp_sw600"
android:layout_marginRight="@dimen/margin_16dp_sw600"
/>


</LinearLayout>

最佳答案

对性能影响最大的可能是下面的代码。你应该使用某种 caching而不是每次都解码位图。

if (profilePic != null) {
try {
Drawable drawable = new BitmapDrawable(BitmapFactory.decodeByteArray(profilePic.getData(), 0, profilePic.getData().length));
holder.profilepicture.setImageDrawable(drawable);
holder.profilepicture.setDrawingCacheEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}

此外,每次调用 getView() 时,您都会创建一个新的 CustomTypography 实例。我假设此类扩展了 Typeface,在这种情况下,您可以只使用在适配器的构造函数中初始化的单个实例。

关于Android ListView 每次滚动都会滞后,即使使用 ViewHolder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33859414/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com