我正在使用计时器来显示每个列表列表行项目的倒计时。但是Listview性能在运行计时器时非常慢。是否有任何解决方案可以使用timer来提高listview的性能。请参阅下面的代码并建议我进行更改。
package com.devpoint.adapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.text.Html;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.RP.database.Repo;
import com.RPRT.database.model.ReserveTable;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.devpoint.PlacesandMaps.GMapV2Direction;
import com.devpoint.PlacesandMaps.PlacesMapActivity;
import com.devpoint.common.GetAllGooglePlaces;
import com.devpoint.common.BackStackingManager.ModuleFragmentBackStackingClass;
import com.devpoint.common.BackStackingManager.ModulesTagsClass.EnumModuleTags;
import com.devpoint.model.ListDetails;
import com.devpoint.retailer.Retailers_Login_Page;
import com.devpoint.rprtgnet.LoadActivity;
import com.devpoint.rprtgnet.MapFragmentActivity;
import com.devpoint.rprtgnet.R;
import com.devpoint.rprtgnet.SplashScreen;
import com.devpoint.sharedpreferences.SessionManager;
import com.devpoint.sharedpreferences.SharedPreference;
import com.devpoint.tabsswipe.ListOngoing;
import com.devpoint.tabsswipe.SwipeViewPagerAdapter;
import com.devpoint.user.DetailsViewpagerFragment;
import com.devpoint.user.PostLogcatErrors;
import com.devpoint.volley.AppController;
import com.google.android.gms.maps.GoogleMap;
import com.squareup.picasso.Picasso;
import android.view.animation.Transformation;
@SuppressLint({ "InflateParams", "ShowToast" })
public class ProductListAdapter extends ArrayAdapter<ListDetails> {
private Activity context;
CopyOnWriteArrayList<ListDetails> products;
SharedPreference sharedPreference;
public static com.android.volley.toolbox.ImageLoader imageLoader;
LayoutInflater inflater;
//ViewHolder holder;
protected String Day = "";
public static View alertLayout;
private static GMapV2Direction gmapdirection;
public static GoogleMap gmap;
protected Document doc;
static final int ANIMATION_DURATION = 200;
String Key;
ProductListAdapter adproductListAdapter;
ListView adswipelisview;
//TextView timer;
ListDetails product;
SessionManager session;
long blobkedmilliseconds=0;
//String Pagename;
private HashMap<TextView,CountDownTimer> counters;
private View v;
private Repo repoObject;
TextView available;
static class TestViewHolder
{
public TextView tvCounter;
}
public ProductListAdapter(Context context, CopyOnWriteArrayList<ListDetails> products, ProductListAdapter productListAdapter, ListView swipelisview) {
super(context, R.layout.adapter_offer_list_item, products);
this.context = (Activity) context;
this.products = products;
sharedPreference = new SharedPreference();
imageLoader = AppController.getInstance().getImageLoader();
adproductListAdapter=productListAdapter;
adswipelisview=swipelisview;
this.counters = new HashMap<TextView, CountDownTimer>();
session = SessionManager.getInstance(context);
inflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
}
private class ViewHolder {
TextView productNameTxt;
//TextView Ratingsno;
TextView productPriceTxt;
//TextView timedist;
TableLayout distancesection;
TextView categoryname;
TextView Modulename;
//ImageView favoriteImg;
RatingBar rb;
ImageView OfferImage;
//ImageView MapImage;
ImageView listimage;
public TextView distance;
public ImageView indicator;
TextView timer;
TextView move;
TextView areaname;
Button blockornotifybtn;
//TextView Postedon;
}
@Override
public int getCount() {
return products.size();
}
@Override
public ListDetails getItem(int position) {
return products.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint("ResourceAsColor")
@Override
public View getView(final int po, View convertView, final ViewGroup parent) {
try {
ViewHolder holder = null;
Day = "";
product = products.get(po);
v= convertView;
session.createPageID(String.valueOf(po));
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.listitem_final, parent,
false);
holder.productNameTxt = (TextView) convertView
.findViewById(R.id.name);
holder.productPriceTxt = (TextView) convertView
.findViewById(R.id.listview_description);
holder.distance = (TextView) convertView
.findViewById(R.id.listview_distane);
holder.rb = (RatingBar) convertView
.findViewById(R.id.ratingbar);
holder.timer = (TextView) convertView.findViewById(R.id.time);
holder.categoryname = (TextView) convertView
.findViewById(R.id.Categoryname);
holder.Modulename = (TextView) convertView
.findViewById(R.id.modulename);
holder.listimage = (ImageView) convertView
.findViewById(R.id.list_image);
holder.blockornotifybtn = (Button)convertView
.findViewById(R.id.blockornotifybtn);
holder.areaname = (TextView) convertView
.findViewById(R.id.areaname);
available = (TextView) convertView
.findViewById(R.id.available);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Typeface type = Typeface.createFromAsset(context.getAssets(),"fonts/roboto/Oswald-Regular.ttf");
holder.productNameTxt.setTypeface(type);
holder.distance.setTypeface(type);
available.setText("Available: "+product.getAvailable());
available.setTypeface(type);
holder.productNameTxt.setText(product.getShopName());
holder.areaname.setText(product.getAreaName());
repoObject = SplashScreen.getRepo();
ReserveTable Reserved = repoObject.rReserveoffer
.getByOpportunityId(Integer.parseInt(product.getOfferID()));
if(Reserved==null)
{
holder.blockornotifybtn.setBackgroundResource(R.drawable.block);
holder.blockornotifybtn.setEnabled(true);
available.setVisibility(View.VISIBLE);
blobkedmilliseconds = 0;
}
else
{
holder.blockornotifybtn.setBackgroundResource(R.drawable.blocked);
holder.blockornotifybtn.setEnabled(false);
available.setVisibility(View.GONE);
blobkedmilliseconds = 300000;
}
holder.Modulename.setText(product.getModuleId());
holder.productPriceTxt.setText(product.getDeal() + "");
holder.rb.setRating(Float.valueOf(product.getRatingAvg()));
holder.distance.setText(String.valueOf(product.getDistance())
+ " Km");
holder.categoryname.setText(product.getCategoryName());
Picasso.with(context).load(product.getListImage()).into(holder.listimage);
final TextView tv = holder.timer;
CountDownTimer cdt = counters.get(tv);
if(cdt!=null)
{
cdt.cancel();
cdt=null;
}
cdt = new CountDownTimer(product.getOfferDifferenceTime()+blobkedmilliseconds, 1000)
{
@Override
public void onTick(long millisUntilFinished)
{
int minutes = 0;
int seconds = 0;
String sDate = "";
if(millisUntilFinished > DateUtils.MINUTE_IN_MILLIS)
{
minutes = (int) (millisUntilFinished / DateUtils.MINUTE_IN_MILLIS);
}
millisUntilFinished -= (minutes*DateUtils.MINUTE_IN_MILLIS);
if(millisUntilFinished > DateUtils.SECOND_IN_MILLIS)
{
seconds = (int) (millisUntilFinished / DateUtils.SECOND_IN_MILLIS);
}
sDate += " "+"00"+":"+String.format("%02d",minutes)+":"+String.format("%02d",seconds);
tv.setText(sDate.trim());
}
@Override
public void onFinish() {
tv.setText("Finished");
final Animation animation = AnimationUtils.loadAnimation(
context, android.R.anim.slide_in_left);
// v.startAnimation(animation);
Handler handle = new Handler();
handle.postDelayed(new Runnable() {
public void run() {
if(v!=null)
{
((Activity) v.getContext()).runOnUiThread(new Runnable() {
@Override
public void run() {
CopyOnWriteArrayList<ListDetails> produc = new CopyOnWriteArrayList<>();
for (ListDetails Pro : products) {
if(Pro.getOfferDifferenceTime()<0)
{
// produc.add(Pro);
}
else
{
produc.add(Pro);
}
}
adproductListAdapter = new ProductListAdapter(
LoadActivity.activity, produc,adproductListAdapter,adswipelisview);
adswipelisview
.setAdapter(adproductListAdapter);
adproductListAdapter.notifyDataSetChanged();
}
});
}
else
{
try {
((Activity) v.getContext()).runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}, 1000);
}
};
counters.put(tv, cdt);
cdt.start();
return convertView;
} catch (Exception e) {
e.printStackTrace();
PostLogcatErrors ple = new PostLogcatErrors();
ple.PostLogcatErorrs(e);
}
return convertView;
}
protected JSONObject getSaveViewUserParams() {
JSONObject params = new JSONObject();
try {
params.put("BlockedUserId", session.getUserRegisterID());
params.put("OpportunityId", product.getOfferID());
params.put("BlockText","Blocked");
params.put("KeyValue", Key);
params.put("DeviceId", session.getDeviceId());
} catch (JSONException e) {
e.printStackTrace();
PostLogcatErrors ple = new PostLogcatErrors();
ple.PostLogcatErorrs(e);
}
return params;
}
}
答案 0 :(得分:1)
在我的案例中,我解决了这个问题。我没有在 getView()中设置计时器处理程序,而是每次 getView时设置当前时间与TextView所需时间之间的时差调用()。所以将你的代码移回 getView():
long outputTime = Math.abs(promoAction.timer_end
- System.currentTimeMillis());
Date date = new java.util.Date(outputTime);
String result = new SimpleDateFormat("hh:mm:ss").format(date);
tv.setText(result);
然后在活动中创建一个处理程序,以便在 listview的适配器上每隔一分钟调用 notifyDatasetChanged():
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
myAdapter.notifyDataSetChanged();
timerHandler.postDelayed(this, 60000); //run every minute
}
};
我在 onPause():
上停止此处理程序@Override
protected void onPause() {
timerHandler.removeCallbacks(timerRunnable);
super.onPause();
}
我在 onResume()上重新开始:
@Override
protected void onResume() {
timerHandler.postDelayed(timerRunnable, 500);
super.onResume();
}
就是这样。 :)
希望它有所帮助。有关详细信息ListView and items with countdown timer