代码之家  ›  专栏  ›  技术社区  ›  Dimon

用SharedPreferences中的对象填充的RecyclerView速度慢且滞后

  •  0
  • Dimon  · 技术社区  · 6 年前

    我正在构建一个应用程序,其中包含从SharedPreferences检索到的对象的RecyclerView。

    这是我的适配器

    public class ShiftAdapter extends RecyclerView.Adapter<ShiftAdapter.ViewHolder>{
    
        private List<Shift> mDataSet;
        private Context mContext;
        private static final String TAG = "ShiftAdapter";
        public int previousExpandedPosition = -1;
        public int mExpandedPosition = -1;
        private static SharedPreferences mPrefs;
        private LinearLayout mShiftIn;
        private LinearLayout mShiftOut;
        private Boolean isStart;
        private Date shiftIn;
        private Date shiftOut;
        private Date mDate;
        public EditText mshiftInText;
        public EditText mshiftOutText;
        public Date date;
    
    
    
        public ShiftAdapter(Context context, List<Shift> list) {
            mDataSet = list;
            mContext = context;
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder {
    
            public TextView mDate;
            public TextView mTime;
            public TextView mPay;
            public RelativeLayout mRelativeLayout;
            public LinearLayout mExepandableLayout;
            public Date mshiftIn;
            public Date mshiftOut;
            public EditText mshiftInText;
            public EditText mshiftOutText;
            public Button mUpdateButton;
            public Button mDeleteButton;
    
    
    
            public ViewHolder(View v) {
                super(v);
                mDate = (TextView) v.findViewById(R.id.date_TV);
                mTime = (TextView) v.findViewById(R.id.time_TV);
                mPay = (TextView) v.findViewById(R.id.pay_TV);
                mRelativeLayout = (RelativeLayout) v.findViewById(R.id.rel_layout);
                mExepandableLayout = (LinearLayout) v.findViewById(R.id.expandableLayout);
                mshiftInText = (EditText) v.findViewById(R.id.setShiftIn);
                mshiftOutText = (EditText) v.findViewById(R.id.setShiftOut);
                mUpdateButton = (Button) v.findViewById(R.id.updateButton);
                mDeleteButton = (Button) v.findViewById(R.id.deleteButton);
            }
        }
    
        @Override
        public ShiftAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(mContext)
                    .inflate(R.layout.shift, parent, false);
            ViewHolder vh = new ViewHolder(itemView);
            return vh;
        }
    
    
        //TODO:Bind all the view elements to Shift Properties
            @Override
            public void onBindViewHolder(@NonNull ViewHolder holder, int i) {
    
                // Format double
                String hours = new DecimalFormat("##.##").format(mDataSet.get(i).getHours());
                String pay = new DecimalFormat("##.##").format(mDataSet.get(i).getPay());
                //set the Text
                holder.mTime.setText(hours);
                holder.mDate.setText(mDataSet.get(i).dateToString());
                holder.mPay.setText(pay);
                Log.d(TAG, "onBindViewHolder: called");
    
    //            new AsyncTask<>().ex
    
    
                //Expand mExapndableLayout
                final int position = i;
                final boolean isExpanded = position ==mExpandedPosition;
                holder.mExepandableLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
                holder.itemView.setActivated(isExpanded);
    
    //            //set shift Times
    //            shiftIn = mDataSet.get(position).getInDate();
    //            shiftOut = mDataSet.get(position).getInDate();
    
    
    
                if (isExpanded)
                    previousExpandedPosition = position;
    
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mExpandedPosition = isExpanded ? -1:position;
                        notifyItemChanged(previousExpandedPosition);
                        notifyItemChanged(position);
                    }
                });
    
                //fill expandable layout
                holder.mshiftInText.setText(mDataSet.get(position).fullTimeToString(0));
                final EditText in = holder.mshiftInText;
                final EditText out = holder.mshiftOutText;
    
                //edit mShiftIn Text
                holder.mshiftInText.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        isStart =true;
                        timePickerDialog(in,out);
                    }
                });
                holder.mshiftOutText.setText(mDataSet.get(position).fullTimeToString(1));
    
                //edit MshiftOut Text
                holder.mshiftOutText.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        isStart =false;
                        timePickerDialog(in,out);
                    }
                });
    
                //updateButton onClick
                holder.mUpdateButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        try {
                            shiftIn = mDataSet.get(position).getInDate();
                            shiftOut = mDataSet.get(position).getOutDate();
                            if(Validate.getValidate().isDateValid(shiftIn,shiftOut)) {
                                SharedPrefs.getInstance(mContext).editShift(newShift(shiftIn, shiftOut),Integer.toString(position));
                                int length = SharedPrefs.getInstance(mContext).getLength() - 1;
                                if (SharedPrefs.getInstance(mContext).getShift(length) != null) {
                                    Log.d(TAG, "Edit Shift onClick: Success");
                                    SharedPrefs.getInstance(mContext).saveShiftList(SharedPrefs.getInstance(mContext).sortList(SharedPrefs.getInstance(mContext).getShiftList()));
                                    ShiftsFragment.updateUI();
                                    Toast.makeText(mContext, "success", Toast.LENGTH_SHORT).show();
                                }
                            } else {
                                mShiftOut.setBackgroundResource(R.drawable.red_border);
                                Toast.makeText(mContext, "error", Toast.LENGTH_SHORT).show(); }
                        } catch(Exception e){
                            Log.d(TAG, "onDateSelected: "+e.toString());
                            Toast.makeText(mContext,"update FAIL", Toast.LENGTH_SHORT).show();
                        }
                        // update the Shift
                    }
                });
                holder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        areYouSure(mExpandedPosition);
                    }
                });
    
            }
    
        @Override
        public int getItemCount() {
                return mDataSet.size();
            }
    
    
        public Date timePickerDialog(EditText in,EditText out) {
            mshiftInText = in;
            mshiftOutText = out;
            new SingleDateAndTimePickerDialog.Builder(mContext)
                    .title(mContext.getResources().getString(R.string.choose_time))
                    .displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
                        @Override
                        public void onDisplayed(SingleDateAndTimePicker picker) {
                            if(!isStart) {
                                date = mDate;
                            }
                        }
                    }).defaultDate(returnDate(date))
                    .listener(new SingleDateAndTimePickerDialog.Listener() {
                        @Override
                        public void onDateSelected(Date date) {
                            mDate = date;
                            if (isStart) {
                                updateShiftIn(mDate);
                                mshiftInText.setText(dateToString(mDate));
                            } else {
                                updateShiftOut(mDate);
                                mshiftOutText.setText(dateToString(mDate));
                            }
    
                        }
                    }).display();
            return mDate;
        }
        public String dateToString(Date date)
        {
            DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm");
            String string = df.format(date);
            return string;
        }
        private void updateShiftIn(Date date) {
            shiftIn = date;
        }
    
        private void updateShiftOut(Date date) {
            shiftOut = date;
        }
        private Date returnDate(Date date)
        {
            if(date!=null)
            {
                return date;
            }
            else return mDate;
        }
    
        private void areYouSure(int i)
        {
            final String position = Integer.toString(i);
            DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    switch (which){
                        case DialogInterface.BUTTON_POSITIVE:
                            Log.d(TAG, "onClick: isSure=true;");
                            SharedPrefs.getInstance(mContext).removeShift(position);
                            ShiftsFragment.updateUI();
                        case DialogInterface.BUTTON_NEGATIVE:
                            Log.d(TAG, "onClick: isSure= false");
                    }
                }
            };
    
            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
            builder.setMessage(mContext.getResources().getString(R.string.are_you_sure)).setPositiveButton(mContext.getResources().getString(R.string.confirm), dialogClickListener)
                    .setNegativeButton(mContext.getResources().getString(R.string.cancel), dialogClickListener).show();
        }
        private Shift newShift(Date start,Date stop)
        {
            int id = SharedPrefs.getInstance(mContext).getLength();
            Shift shift = new Shift(dateToCalendar(start),dateToCalendar(stop),id);
            return shift;
    
        }
    

    这是一个片段,上面有循环视图

    public class ShiftsFragment extends Fragment {
        private Toolbar mToolbar;
        private TimePicker timePicker1;
        private List<Shift> shiftList = new ArrayList<>();
        private RecyclerView recyclerView;
        private RelativeLayout relativeLayout;
        private RecyclerView.LayoutManager layoutManager;
        private LinearLayout mShiftIn;
        private LinearLayout mShiftOut;
        private Context mContext;
        private ShiftAdapter mAdapter;
        private MenuItem mAdd;
        private Menu optionsMenu;
        private LinearLayout mShiftAddLL;
        private SharedPreferences mPrefs;
        private static FragmentManager mFragmentManager;
        private static final String TAG = "ShiftsFragment";
    
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            Log.d(TAG,"Clicked");
            final View view = inflater.inflate(R.layout.shifts_layout,container,false);
    
            mToolbar = view.findViewById(R.id.topbar);
            mToolbar.inflateMenu(R.menu.toolbarmenu);
            mShiftAddLL = view.findViewById(R.id.add_shiftLayout);
            mAdd = mToolbar.getMenu().getItem(0);
            timePicker1 = (TimePicker) view.findViewById(R.id.timePicker);
    
    
            mFragmentManager = getFragmentManager();
    
    
            //TODO:Add a summary bar on the bottom.
    
            //get the context
            mContext = getContext();
            recyclerView = (RecyclerView) view.findViewById(R.id.shift_list);
    
            // Define a layout for RecyclerView
            layoutManager = new GridLayoutManager(mContext,1);
            recyclerView.setLayoutManager(layoutManager);
    
            // Initialize a new Shift array
            List<Shift> shiftList = initShifts();
            Log.d(TAG,"shift array initiated");
            // Initialize an array list from array
            // Initialize a new instance of RecyclerView Adapter instance
            mAdapter = new ShiftAdapter(mContext,shiftList);
            // Set the adapter for RecyclerView
            recyclerView.setAdapter(mAdapter);
            recyclerView.setNestedScrollingEnabled(false);
            recyclerView.setHasFixedSize(true);
    
    
    
            //Menu add button onClick
            //Opens Add_Shift_Fragment
            mAdd.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem menuItem) {
                    Fragment selectedFragment = new Add_Shift_Fragment();
                    getFragmentManager().beginTransaction().replace(R.id.fragment_container,
                            selectedFragment).commit();
                    return false;
                }
            });
    
    
            return view;
    
    
        }
    
        //Initializes the Shift list from SharedPreferences and returns it.
        private List<Shift> initShifts() {
            return SharedPrefs.getInstance(mContext).getShiftList();
    
        }
    
        public static void updateUI()
        {
            Fragment selectedFragment = new ShiftsFragment();
            mFragmentManager.beginTransaction().replace(R.id.fragment_container,
                    selectedFragment).commit();
        }
    
    
    }
    

    每次我启动ShiftsFragment时,都会有一些帧跳转,而且滚动是不稳定和滞后的。

    也许我的共同偏好处理是什么让事情变慢了?

    public class SharedPrefs {
    
        private static SharedPrefs mSharedPrefs;
        private SharedPreferences mPrefs;
        private SharedPreferences.Editor mPrefsEditor;
        protected Context mContext;
    
        public static final String ID = "shiftList";
    
        private SharedPrefs(Context context) {
            mContext = context;
            mPrefs = context.getSharedPreferences(ID, Context.MODE_PRIVATE);
            mPrefsEditor = mPrefs.edit();
        }
    
        public static SharedPrefs getInstance(Context context) {
    
            if (mSharedPrefs == null) {
                mSharedPrefs = new SharedPrefs(context.getApplicationContext());
            }
            return mSharedPrefs;
        }
    
        public void saveShiftList(List<Shift> shiftList) {
            Gson gson = new Gson();
            String json = gson.toJson(shiftList);
            mPrefsEditor.putString(ID, json);
            mPrefsEditor.apply();
        }
        public void addShift (Shift shift)
        {
            List<Shift> shiftList= getShiftList();
            shiftList.add(shift);
            saveShiftList(shiftList);
    
        }
        //Replaced the shift@id with shift
        public void editShift(Shift shift,String id)
        {
            removeShift(id);
            addShift(shift);
        }
        public void removeShift(String id) {
            List<Shift> shiftList = getShiftList();
            int pos = Integer.parseInt(id);
            shiftList.remove(pos);
            saveShiftList(shiftList);
        }
    
        public void removeShift(int id) {
            List<Shift> shiftList = getShiftList();
            shiftList.remove(id);
            saveShiftList(shiftList);
        }
    
        public  Shift getShift(int id) {
            Gson gson = new Gson();
            List<Shift> shiftList;
            String json = mPrefs.getString(ID, null);
            Type type = new TypeToken<List<Shift>>() {
            }.getType();
            shiftList = gson.fromJson(json, type);
            Shift shift = shiftList.get(id);
            return shift;
        }
    
        public List<Shift> getShiftList() {
            Gson gson = new Gson();
            List<Shift> shiftList;
            String json = mPrefs.getString(ID, null);
            Type type = new TypeToken<List<Shift>>() {
            }.getType();
            shiftList = gson.fromJson(json, type);
            if (shiftList!=null) {
                return shiftList;
            } else{
                shiftList = new ArrayList<>();
                return shiftList;
            }
    
        }
    
        public List<Shift> sortList(List<Shift> shiftList)
        {
            Collections.sort(shiftList, new Comparator<Shift>() {
                public int compare(Shift shift1, Shift shift2) {
                    if (shift1.getShiftStart() == null || shift2.getShiftStart() == null)
                        return 0;
                    return shift1.getShiftStart().compareTo(shift2.getShiftStart());
                }
            });
            return shiftList;
        }
    
        public int getLength()
        {
            return  getShiftList().size();
        }
    }
    

    我只在图像加载中发现了这个问题,而不仅仅是来自SharedPrefs对象的字符串。

    0 回复  |  直到 6 年前