从广播接收器更新回收者视图

时间:2018-07-01 08:17:29

标签: android android-recyclerview broadcastreceiver sectionedrecyclerviewadapter

我正在学习android开发和开发todolist应用。我想添加一项功能,以在完成给定时间后将其从待办事项列表中删除。我正在使用警报管理器来触发广播接收器,该接收器会在时间流逝后从数据集中删除该项目,但是一旦代码运行,此功能似乎将无法正常工作。我收到空指针异常。

这是我的回收站视图适配器的代码-

package Adapters;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import Data.DataBaseHandler;
import Model.Target;
import siddharthbisht.targettracker.R;
public class RecyclerViewAdapter extends 
    RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
    Context context;
    List<Target> targetList;
    private AlertDialog.Builder alertDiaologBuilder;
    private AlertDialog dialog;
    private LayoutInflater inflater;
    DataBaseHandler db;
    public static final String TAG="RecyclerVIewAdapter";
    public RecyclerViewAdapter(Context context){
        this.context=context;
    }
    public RecyclerViewAdapter(Context context, List<Target> targetList) {
        this.context=context;
        this.targetList=targetList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int 
    viewType) {
    View view= 
    LayoutInflater.from(
    parent.getContext()).inflate(R.layout.item_row,parent,false);
    return new ViewHolder(view,context);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Target target=targetList.get(position);
        holder.taskName.setText(target.getTopic());
        holder.finishDate.setText(target.getFinishDate()+"/"+ 
        (target.getFinishMonth()+1)+"/"+target.getFinishYear());
        holder.finishTime.setText(
        target.getFinishHour()+":"+target.getFinishMinute());
        }

        @Override
        public int getItemCount() {
            return targetList.size();
        }

        public  class ViewHolder extends RecyclerView.ViewHolder implements 
        View.OnClickListener{
            public TextView taskName;
            public TextView finishDate;
            public TextView finishTime;
            public ImageView done;
            public ImageView delete;

       public ViewHolder(View itemView, Context ctx) {
            super(itemView);
            context=ctx;
            taskName=itemView.findViewById(R.id.tvTaskName);
            finishDate=itemView.findViewById(R.id.tvFinishDate);
            finishTime=itemView.findViewById(R.id.tvFinishTime);
            done=itemView.findViewById(R.id.ivCompleted);
            delete=itemView.findViewById(R.id.ivDelete);
            delete.setOnClickListener(this);
            done.setOnClickListener(this);
            }

        @Override
        public void onClick(View v) {
            Target target;
            int position=getAdapterPosition();
            switch (v.getId()){
                case R.id.ivDelete:
                    target=targetList.get(position);
                    deleteItem(target.getId());
                    break;
                case R.id.ivCompleted:
                     target=targetList.get(position);
                    moveToDone(target,position);
                    break;
              }
         }

        private void deleteItem(final int id) {
             alertDiaologBuilder=new AlertDialog.Builder(context);
             inflater=LayoutInflater.from(context);
             View view=inflater.inflate(R.layout.confirmation_dialog,null);

             Button noButton=view.findViewById(R.id.noButton);
             Button yesButton=view.findViewById(R.id.yesButton);
             alertDiaologBuilder.setView(view);
             dialog=alertDiaologBuilder.create();
             dialog.show();
             noButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    dialog.dismiss();
                }
             });
             yesButton.setOnClickListener(new View.OnClickListener() {
             @Override
                public void onClick(View v) {
                     //delete the item
                     db=new DataBaseHandler(context);
                     db.DeleteTarget(id);
                     targetList.remove(getAdapterPosition());
                     notifyItemRemoved(getAdapterPosition());
                     dialog.dismiss();
                 }
            });
        }
     }
     public void moveToDone(Target target,int position){
        db=new DataBaseHandler(context);
        db.updateCompletionStatus(target.getId());
        targetList.remove(position);
        Target target1=db.getTarget(target.getId());
        notifyDataSetChanged();
        notifyItemRemoved(position);
        Log.d(TAG,target.getTopic()+" removed");
        Log.d(TAG,"completion status: "+target1.getCompletionStatus());
        Log.d(TAG,"due status: "+target1.getDue());
        }
        public int getTargetPosition(int id){
            int position=0;
            Target target=db.getTarget(id);
            for (Target t: targetList){
            if (t.getId()==target.getId()){
                position=targetList.indexOf(t);
                break;
                }
             }
              return position;
             }

     }

这是我在其中将项目添加到列表中的活动的代码-

package Activities;

import android.app.AlarmManager;
import android.app.DatePickerDialog;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Calendar;
import Data.DataBaseHandler; 
import Model.Target;
import Receiver.AlarmReceiver;
import Receiver.SetDueOnComplete;
import Util.AlarmCreater;
import Util.CurrentDateAndTime;
import Util.Validator;
import siddharthbisht.targettracker.R;
public class AddTargetActivity extends AppCompatActivity implements 
    View.OnClickListener {
    private EditText etTopic;
    private TextView date;
    private TextView time;
    private Button submit;
    DataBaseHandler handler;
    private int mYear, mMonth, mDay, mHour, mMinute;
    private int sYear, sMonth, sDate, sHour, sMinute;
    public AlarmCreater creater;
    public Validator validator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_target2);
        etTopic = findViewById(R.id.etAddTopicName);
        date = findViewById(R.id.tvDateToStore);
        time = findViewById(R.id.tvTimeToStore);
        submit = findViewById(R.id.btSubmitAdd);
        handler=new DataBaseHandler(this);
        initializeDateTime();
        date.setOnClickListener(this);
        time.setOnClickListener(this);
        submit.setOnClickListener(this);
        creater=new AlarmCreater();
        validator=new Validator();
        }
    public void initializeDateTime() {
        Calendar calendar = Calendar.getInstance();
        mYear=calendar.get(Calendar.YEAR);
        mMonth=calendar.get(Calendar.MONTH);
        mDay=calendar.get(Calendar.DAY_OF_MONTH);
        mHour=calendar.get(Calendar.HOUR_OF_DAY);
        mMinute=calendar.get(Calendar.MINUTE);
        int trueMonth=mMonth+1;
        String dateStr = mDay + "/" + trueMonth+ "/"+mYear;
        String timeStr = mHour + ":" + mMinute;
        date.setText(dateStr);
        time.setText(timeStr);
     }
    private void saveTargetToDb(View v,int year, int month, int date, int 
         hours, int minutes) {
        Target target = new Target();
        String topic = etTopic.getText().toString();
        target.setTopic(topic);
        target.setFinishDate(date);
        target.setFinishMonth(month);
        target.setFinishYear(year);
        target.setFinishHour(hours);
        target.setFinishMinute(minutes);
        target.setDue(0);
        target.setCompletionStatus(0);
        //Save to database
        handler.addTarget(target);
        Log.d("added target:",target.getTopic());
        int id=handler.getLastItem().getId();
        Log.d("added item id:",String.valueOf(id));
        //Getting alarm time in millis
        Long timeinMillis=getTimeInMillis(year,month,date,hours,minutes);
        creater.setAlarm(this,timeinMillis,id,target.getTopic());
        setDueStatus(id,timeinMillis);
        Snackbar.make(v,  target.getTopic()+" Saved", 
        Snackbar.LENGTH_LONG).show();
        new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            Intent intent=new 
            Intent(AddTargetActivity.this,MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
            finish();
            }
        }, 1000);

    }

    @Override
    public void onClick(View v) {
        initializeDateTime();
        switch (v.getId()) {
            case R.id.tvDateToStore:
                DatePickerDialog datePickerDialog = new 
                DatePickerDialog(AddTargetActivity.this,
                    new DatePickerDialog.OnDateSetListener() {

                        @Override
                        public void onDateSet(DatePicker view, int year,
                                              int monthOfYear, int 
                             dayOfMonth) {
                            sDate = dayOfMonth;
                            sMonth = monthOfYear;
                            sYear = year;
                            date.setText(sDate + "/" + (sMonth + 1) + "/" + 
                             sYear);
                            Log.d("DatePicker:", String.valueOf(sDate) + "/" 
                            + String.valueOf(sMonth) + "/" + 
                              String.valueOf(sYear));
                        }
                    }, mYear, mMonth, mDay);
            datePickerDialog.show();
            break;
        case R.id.tvTimeToStore:
            // Launch Time Picker Dialog
            TimePickerDialog timePickerDialog = new 
            TimePickerDialog(AddTargetActivity.this,
                    new TimePickerDialog.OnTimeSetListener() {

                        @Override
                        public void onTimeSet(TimePicker view, int hourOfDay,
                                              int minute) {
                            sHour = hourOfDay;
                            sMinute = minute;
                            time.setText(sHour + ":" + sMinute);
                            Log.d("timePicker:", String.valueOf(sHour) + ":" 
                             + String.valueOf(sMinute));

                        }
                    }, mHour, mMinute, false);
            timePickerDialog.show();

            break;
        case R.id.btSubmitAdd:
            Log.d("Inside if 1:time:", String.valueOf(sYear) + "/" + 
               String.valueOf(sMonth) + "/" + String.valueOf(sDate) + " //" + 
               String.valueOf(sHour) + ":" + String.valueOf(sMinute));
            saveTargetToDb(v, sYear, sMonth, sDate, sHour, sMinute);

           /* if (!etTopic.getText().toString().isEmpty()&& 
             validator.validateTime(sHour,sMinute) && 
             validator.validateDate(sDate,sMonth,sYear,sHour,sMinute)) {

            }
            else{
                Toast.makeText(AddTargetActivity.this,"Enter correct 
            Values",Toast.LENGTH_SHORT).show();
            }*/
            }
           }


    public long getTimeInMillis(int year,int month,int date,int hour,int 
         minutes) 
    {
        Calendar calendar=Calendar.getInstance();
        calendar.set(year,month,date,hour,minutes,0);
        return calendar.getTimeInMillis();
    }
public void setDueStatus(int id,long timeInMillis){
    AlarmManager alarmManager=(AlarmManager) 
    this.getSystemService(Context.ALARM_SERVICE);
    Intent intent=new Intent(this, SetDueOnComplete.class);
    intent.putExtra("id",id);
    PendingIntent 
   pendingIntent= PendingIntent.getBroadcast(
    this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.set(AlarmManager.RTC_WAKEUP,timeInMillis,pendingIntent);
    Toast.makeText(this,"due status is set",Toast.LENGTH_SHORT).show();
    Log.d("Alarm:","alarm set for "+String.valueOf(timeInMillis));
}

}

广播接收器类---

package Receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Adapter;
import Adapters.RecyclerViewAdapter;
import Data.DataBaseHandler;
import Fragments.CurrentTaskFragment;
import Model.Target;

public class SetDueOnComplete extends BroadcastReceiver {
    DataBaseHandler handler;
    CurrentTaskFragment fragment;
    RecyclerViewAdapter adapter;
    private static final String TAG="SetDuoComplete";
    public SetDueOnComplete() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        handler=new DataBaseHandler(context);
        Bundle bundle=intent.getExtras();
        adapter=new RecyclerViewAdapter(context);
        int id=bundle.getInt("id");
        int position=adapter.getTargetPosition(id);
        adapter.moveToDone(handler.getTarget(id),position);
        Log.d(TAG,String.valueOf(id));
        fragment=new CurrentTaskFragment();
        fragment.initializeData();
        Log.d(TAG,String.valueOf(id)+" removed");
    }
}

这是片段类,我在其中显示列表-

package Fragments;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

import java.util.ArrayList;
import java.util.List;

import Adapters.RecyclerViewAdapter;
import Data.DataBaseHandler;
import Model.Target;
import siddharthbisht.targettracker.R;


public class CurrentTaskFragment extends Fragment {
    RecyclerView recyclerView;
    private RecyclerViewAdapter adapter;
    private List<Target> targetList;
    private List<Target> listItems;
    private DataBaseHandler db;

    private OnFragmentInteractionListener mListener;

    public CurrentTaskFragment() {
        // Required empty public constructor
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view= inflater.inflate(R.layout.fragment_current_task, container, false);
        db=new DataBaseHandler(this.getContext());
        recyclerView=view.findViewById(R.id.rvList);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
        targetList=new ArrayList<>();
        listItems=new ArrayList<>();
        initializeData();
        return view;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }


    public void initializeData(){

        //Get items from database

        targetList=db.getAllCurrentTargets();

        for(Target c: targetList){
            Target target=new Target();
            target.setTopic(c.getTopic());
            target.setFinishDate(c.getFinishDate());
            target.setFinishMonth(c.getFinishMonth());
            target.setFinishYear(c.getFinishYear());
            target.setFinishHour(c.getFinishHour());
            target.setFinishMinute(c.getFinishMinute());
            target.setId(c.getId());
            listItems.add(target);
            Log.d("fragement:",target.getTopic()+" added");
            Log.d("fragment: ",String.valueOf(target.getCompletionStatus()));

        }
        adapter=new RecyclerViewAdapter(this.getContext(),listItems);
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }


}

0 个答案:

没有答案