android - 当计时器在每一行内运行时如何提高列表性能

标签 android performance listview timer android-adapter

我正在使用计时器来显示每个列表列表行项目的倒计时。但是运行计时器时 Listview 性能非常慢。是否有任何解决方案可以提高带有计时器的 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;
        }


}

最佳答案

在我的案例中,我以不同的方式解决了这个问题。我没有在 getView() 中设置一个 timer handler,而是在每次 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);

然后在 Activity 中创建一个处理程序,每隔一分钟在 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

关于android - 当计时器在每一行内运行时如何提高列表性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35357639/

相关文章:

android - 来自 SQLite 查询的 CursorIndexOutOfBoundsException

c - 在 Linux over windows 中共享内存性能(同步开销 : Semaphore)

performance - 在excel vba中格式化需要很长时间

android - 大 ListView 问题

android - HTML5跨平台应用的架构类型

Android 应用程序未在市场中显示为 "update available"

c# - 如何查找列表的元素是否在另一个列表中?

java - ListView 对话框中的空指针异常

wpf - 拉伸(stretch)空的 WPF ListView 以占用剩余空间

java - 图片上传崩溃