mainactivity 中的 cardview 按钮 onclicklistener 删除特定联系人,给出空指针异常
cardview button onclicklistener in mainactivity to delete a specific contact giving null pointer exception
虽然我能够从 sqlite 数据库中删除选定的联系人,但我似乎无法在执行此操作时正确更新 recyclerview。我尝试在 custom adapter
中使用 notifyDataSetChanged()
命令,但没有给出任何结果。
这是 customAdapter
.
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private Context context;
public ArrayList Contact_id, Contact_Name, Contact_number;
public ImageView mDelete, mMakeCall, mSendText;
public String Latitude="0",Longitude="0";
DatabaseHelper myDB;
public interface OnItemClickListener {
void onDeleteClick(int position);
}
CustomAdapter(Context context, ArrayList Contact_id, ArrayList Contact_Name, ArrayList Contact_number,String mLatitude,String mLongitude) {
this.context = context;
this.Contact_id = Contact_id;
this.Contact_Name = Contact_Name;
this.Contact_number = Contact_number;
this.Latitude= mLatitude;
this.Longitude=mLongitude;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.cardview_contact_item, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.Contact_id_txt.setText(String.valueOf(Contact_id.get(position)));
holder.Contact_Name_txt.setText(String.valueOf(Contact_Name.get(position)));
holder.Contact_Number_txt.setText(String.valueOf(Contact_number.get(position)));
}
@Override
public int getItemCount() {
return Contact_id.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView Contact_id_txt, Contact_Name_txt, Contact_Number_txt;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
mDelete = itemView.findViewById(R.id.Cardview_delete);
mMakeCall = itemView.findViewById(R.id.Cardview_MakeCall);
mSendText = itemView.findViewById(R.id.Cardview_MakeText);
Contact_Name_txt = itemView.findViewById(R.id.CardView_Name);
Contact_Number_txt = itemView.findViewById(R.id.CardView_Number);
Contact_id_txt = itemView.findViewById(R.id.cardview_Contact_Id);
SharedPreferences mPreference = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = mPreference.edit();
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
int contactId = Integer.parseInt(Contact_id_txt.getText().toString());
Toast.makeText(context, "int id ="+contactId+"Contact id ="+Contact_id, Toast.LENGTH_SHORT).show();
DatabaseHelper databaseHelper = new DatabaseHelper(context);
boolean success = databaseHelper.deleteOne(contactId);
Toast.makeText(context, "Contact Deleted", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
});
mMakeCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "Calling Contact", Toast.LENGTH_SHORT).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
String phonenumber = Contact_Number_txt.getText().toString();
callIntent.setData(Uri.parse("tel:" + phonenumber));
try {
context.startActivity(callIntent);
} catch (Exception ex) {
Toast.makeText(context, "Call Failed", Toast.LENGTH_SHORT).show();
ex.printStackTrace();
}
}
});
mSendText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//
Intent smsIntent = new Intent(Intent.ACTION_SENDTO);
String phonenumber = Contact_Number_txt.getText().toString();
try {
SmsManager mySmsManager = SmsManager.getDefault();
mySmsManager.sendTextMessage(phonenumber, null, "I NEED HELP AT LATITUDE:" + Latitude + "LONGITUDE" + Longitude+" https://www.google.com/maps/search/?api=1&query="+Latitude+","+Longitude, null, null);
Toast.makeText(context, "Alert Message Sent", Toast.LENGTH_SHORT).show();
Toast.makeText(context, "LATITUDE:" + Latitude, Toast.LENGTH_SHORT).show();
Toast.makeText(context, "LONGITUDE:" + Longitude, Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(context, "Something went wrong/Fields are Empty", Toast.LENGTH_SHORT).show();
}
//Toast.makeText(context,"The number is "+phonenumber, Toast.LENGTH_SHORT).show();
}
});
}//End of OnCreate
@Override
public void onClick(View view) {
}
}
//public void removeItem(int position){}
}
它工作正常,但只有在我退出并输入 mainActivity
一次后才会更新。
我尝试在 mainactivity 本身中实现 notifyDataSetChanged()
方法,但是当我这样做时我得到了 nullpointerexception
。
ImageView mDelete;
mDelete = findViewById(R.id.Cardview_delete);
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
customAdapter.notifyDataSetChanged();
}
});
这是错误代码
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.rakshakmk1/com.example.rakshakmk1.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.rakshakmk1.MainActivity.onCreate(MainActivity.java:150)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
XML 布局:RecyclerView/Cardview
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="102dp"
>
<ImageView
android:id="@+id/Cardview_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/dialog_rounded_bg"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp" />
<ImageView
android:id="@+id/Cardview_MakeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/ic_location_icon_final" />
<ImageView
android:id="@+id/Cardview_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.981"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.05"
app:srcCompat="@drawable/ic_delete_circle_icon_final" />
<TextView
android:id="@+id/CardView_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Emergency Contact"
android:textColor="#000000"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.101"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.259"
android:paddingRight="50sp"/>
<TextView
android:id="@+id/CardView_Number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number"
android:textColor="#858585"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.079"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.794" />
<ImageView
android:id="@+id/Cardview_MakeCall"
android:layout_width="37dp"
android:layout_height="36dp"
app:layout_constraintBottom_toBottomOf="@+id/Cardview_MakeText"
app:layout_constraintEnd_toStartOf="@+id/Cardview_MakeText"
app:layout_constraintHorizontal_bias="0.974"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/Cardview_MakeText"
app:layout_constraintVertical_bias="0.444"
app:srcCompat="@drawable/ic_call_icon_final" />
<TextView
android:id="@+id/cardview_Contact_Id"
android:layout_width="23dp"
android:layout_height="15dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/CardView_Name"
app:layout_constraintEnd_toStartOf="@+id/Cardview_delete"
app:layout_constraintHorizontal_bias="0.469"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
XML 布局:MainActivity
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_background"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/activity_rounded_bg"
android:layout_marginTop="50dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="true"
android:paddingHorizontal="0dp"
android:paddingTop="10dp"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="67dp"
tools:listitem="@layout/cardview_contact_item">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
<ImageButton
android:id="@+id/btnAddContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/ic_add_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
这是创建数组列表的 MainActivity
。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
//widgets
public ImageButton eAddContact;
RecyclerView recyclerView;
DatabaseHelper myDB;
ArrayList<String> Contact_id, Contact_Name, Contact_Number;
CustomAdapter customAdapter;
Button btnEnterContact;
private FusedLocationProviderClient fusedLocationProviderClient;
//Google's api for location services.
//private final int REQUEST_CHECK_CODE=8989;
private LocationSettingsRequest.Builder builder;
private String mLatitude,mLongitude;
private static final int REQUEST_SMS = 0;
private static final int REQUEST_LOCATION = 1;
private static final int REQUEST_CALL =2;
Intent mIntent;
LocationManager locationManager;
LocationRequest locationRequest;
LocationCallback locationCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//permissions
if(ContextCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS)!=PackageManager.PERMISSION_GRANTED)
{
//if permission is not granted then check if user has denied
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.SEND_SMS)){
}else
{
//popup for asking permission
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},REQUEST_SMS);
}
}
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED)
{
//if permission is not granted then check if user has denied
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_FINE_LOCATION)){
}else
{
//popup for asking permission
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION);
}
}
if(ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED)
{
//if permission is not granted then check if user has denied
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CALL_PHONE)){
}else
{
//popup for asking permission
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CALL_PHONE},REQUEST_CALL);
}
}
eAddContact = findViewById(R.id.btnAddContact);
eAddContact.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick:opening dialog");
Dialog_AddContact dialog = new Dialog_AddContact();
dialog.show(getSupportFragmentManager(), "Add Contact Dialog");
}
});
//Toast.makeText(getApplicationContext(),"@#",Toast.LENGTH_SHORT).show();
myDB = new DatabaseHelper(MainActivity.this);
Contact_id = new ArrayList<>();
Contact_Name = new ArrayList<>();
Contact_Number = new ArrayList<>();
recyclerView = findViewById(R.id.RecyclerView);
Cursor cursor= myDB.getEveryone();
customAdapter = new CustomAdapter(MainActivity.this, Contact_id, Contact_Name, Contact_Number,mLatitude,mLongitude);
//set all the properties of LocationRequest
locationRequest = new LocationRequest();
//how often does location check occur
locationRequest.setInterval(1000*30);
locationRequest.setFastestInterval(1000*50);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
//Display cardview data
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
customAdapter.notifyDataSetChanged();
//update gps data
updateGPS();
storeDataInArrays();
/*
ImageView mDelete;
mDelete = findViewById(R.id.Cardview_delete);
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
customAdapter.notifyDataSetChanged();
}
});
*/
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//will check requestCode
switch(requestCode)
{
case REQUEST_SMS:
{
//check if length of grantResults is greater than 0 and equal to PERMISSION_GRANTED
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this,"SMS Permission Granted",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this,"SMS Permission Denied",Toast.LENGTH_LONG).show();
}
}
case REQUEST_LOCATION:
{
//check if length of grantResults is greater than 0 and equal to PERMISSION_GRANTED
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this,"Location Permission Granted",Toast.LENGTH_LONG).show();
updateGPS();
}
else
{
Toast.makeText(this,"Location Permission Denied",Toast.LENGTH_LONG).show();
}
}
case REQUEST_CALL:
{
//check if length of grantResults is greater than 0 and equal to PERMISSION_GRANTED
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this,"Call Permission Granted",Toast.LENGTH_LONG).show();
updateGPS();
}
else
{
Toast.makeText(this,"Call Permission Denied",Toast.LENGTH_LONG).show();
}
}
}//switch
}
private void updateGPS(){
//get permissions from the user to track GPS
//get current location
//update string
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MainActivity.this);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
//user gave the permissions
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
//we got permissions. put the values of location.
updateLocation(location);
}
});
}
else{
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION);
}
}
}
private void updateLocation(Location location) {
//update the location of the person
mLatitude = String.valueOf(location.getLatitude());
mLongitude = String.valueOf(location.getLongitude());
Toast.makeText(this,"Latitude = "+mLatitude,Toast.LENGTH_SHORT).show();
Toast.makeText(this,"Longitude = "+mLongitude,Toast.LENGTH_SHORT).show();
Cursor cursor= myDB.getEveryone();
recyclerView.setAdapter(new CustomAdapter(MainActivity.this, Contact_id, Contact_Name, Contact_Number,mLatitude,mLongitude));
recyclerView.invalidate();
}
void storeDataInArrays() {
customAdapter.notifyDataSetChanged();
Contact_id.clear();
Contact_Name.clear();
Contact_Number.clear();
Cursor cursor = myDB.getEveryone();
if (cursor.getCount() == 0) {
//Add blank page
} else {
while (cursor.moveToNext()) {
Contact_id.add(cursor.getString(0));
Contact_Name.add(cursor.getString(1));
Contact_Number.add(cursor.getString(2));
}
}
recyclerView.setAdapter(new CustomAdapter(MainActivity.this, Contact_id, Contact_Name, Contact_Number,mLatitude,mLongitude));
customAdapter.notifyDataSetChanged();
}
public void removeItem(int position){
Contact_id.remove(true);
storeDataInArrays();
customAdapter.notifyDataSetChanged();
}
//public void onRequestPermissionResult(int requestCOde,String permissions[],int[] grantResults){}//method
public void onLocationChanged(Location location) {
}
public void onProviderDisabled(String provider) {
Log.d("Latitude","disable");
}
public void onProviderEnabled(String provider) {
Log.d("Latitude","enable");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Latitude","status");
}
}
我好像做错了什么?
非常感谢任何帮助。
我不太确定,但更新 ArrayList(s) 应该可以。
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
int contactId = Integer.parseInt(Contact_id_txt.getText().toString());
Toast.makeText(context, "int id ="+contactId+"Contact id ="+Contact_id, Toast.LENGTH_SHORT).show();
DatabaseHelper databaseHelper = new DatabaseHelper(context);
boolean success = databaseHelper.deleteOne(contactId);
Contact_id.remove(Integer.valueOf(contactId));
Toast.makeText(context, "Contact Deleted", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
我认为 Contact_Name 和 Contact_number 可能也需要更新,但这取决于如何MainActivity 代码会处理它。
虽然我能够从 sqlite 数据库中删除选定的联系人,但我似乎无法在执行此操作时正确更新 recyclerview。我尝试在 custom adapter
中使用 notifyDataSetChanged()
命令,但没有给出任何结果。
这是 customAdapter
.
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private Context context;
public ArrayList Contact_id, Contact_Name, Contact_number;
public ImageView mDelete, mMakeCall, mSendText;
public String Latitude="0",Longitude="0";
DatabaseHelper myDB;
public interface OnItemClickListener {
void onDeleteClick(int position);
}
CustomAdapter(Context context, ArrayList Contact_id, ArrayList Contact_Name, ArrayList Contact_number,String mLatitude,String mLongitude) {
this.context = context;
this.Contact_id = Contact_id;
this.Contact_Name = Contact_Name;
this.Contact_number = Contact_number;
this.Latitude= mLatitude;
this.Longitude=mLongitude;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.cardview_contact_item, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.Contact_id_txt.setText(String.valueOf(Contact_id.get(position)));
holder.Contact_Name_txt.setText(String.valueOf(Contact_Name.get(position)));
holder.Contact_Number_txt.setText(String.valueOf(Contact_number.get(position)));
}
@Override
public int getItemCount() {
return Contact_id.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView Contact_id_txt, Contact_Name_txt, Contact_Number_txt;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
mDelete = itemView.findViewById(R.id.Cardview_delete);
mMakeCall = itemView.findViewById(R.id.Cardview_MakeCall);
mSendText = itemView.findViewById(R.id.Cardview_MakeText);
Contact_Name_txt = itemView.findViewById(R.id.CardView_Name);
Contact_Number_txt = itemView.findViewById(R.id.CardView_Number);
Contact_id_txt = itemView.findViewById(R.id.cardview_Contact_Id);
SharedPreferences mPreference = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = mPreference.edit();
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
int contactId = Integer.parseInt(Contact_id_txt.getText().toString());
Toast.makeText(context, "int id ="+contactId+"Contact id ="+Contact_id, Toast.LENGTH_SHORT).show();
DatabaseHelper databaseHelper = new DatabaseHelper(context);
boolean success = databaseHelper.deleteOne(contactId);
Toast.makeText(context, "Contact Deleted", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
});
mMakeCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "Calling Contact", Toast.LENGTH_SHORT).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
String phonenumber = Contact_Number_txt.getText().toString();
callIntent.setData(Uri.parse("tel:" + phonenumber));
try {
context.startActivity(callIntent);
} catch (Exception ex) {
Toast.makeText(context, "Call Failed", Toast.LENGTH_SHORT).show();
ex.printStackTrace();
}
}
});
mSendText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//
Intent smsIntent = new Intent(Intent.ACTION_SENDTO);
String phonenumber = Contact_Number_txt.getText().toString();
try {
SmsManager mySmsManager = SmsManager.getDefault();
mySmsManager.sendTextMessage(phonenumber, null, "I NEED HELP AT LATITUDE:" + Latitude + "LONGITUDE" + Longitude+" https://www.google.com/maps/search/?api=1&query="+Latitude+","+Longitude, null, null);
Toast.makeText(context, "Alert Message Sent", Toast.LENGTH_SHORT).show();
Toast.makeText(context, "LATITUDE:" + Latitude, Toast.LENGTH_SHORT).show();
Toast.makeText(context, "LONGITUDE:" + Longitude, Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(context, "Something went wrong/Fields are Empty", Toast.LENGTH_SHORT).show();
}
//Toast.makeText(context,"The number is "+phonenumber, Toast.LENGTH_SHORT).show();
}
});
}//End of OnCreate
@Override
public void onClick(View view) {
}
}
//public void removeItem(int position){}
}
它工作正常,但只有在我退出并输入 mainActivity
一次后才会更新。
我尝试在 mainactivity 本身中实现 notifyDataSetChanged()
方法,但是当我这样做时我得到了 nullpointerexception
。
ImageView mDelete;
mDelete = findViewById(R.id.Cardview_delete);
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
customAdapter.notifyDataSetChanged();
}
});
这是错误代码
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.rakshakmk1/com.example.rakshakmk1.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.rakshakmk1.MainActivity.onCreate(MainActivity.java:150)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
XML 布局:RecyclerView/Cardview
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="102dp"
>
<ImageView
android:id="@+id/Cardview_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/dialog_rounded_bg"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp" />
<ImageView
android:id="@+id/Cardview_MakeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/ic_location_icon_final" />
<ImageView
android:id="@+id/Cardview_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.981"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.05"
app:srcCompat="@drawable/ic_delete_circle_icon_final" />
<TextView
android:id="@+id/CardView_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Emergency Contact"
android:textColor="#000000"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.101"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.259"
android:paddingRight="50sp"/>
<TextView
android:id="@+id/CardView_Number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number"
android:textColor="#858585"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.079"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.794" />
<ImageView
android:id="@+id/Cardview_MakeCall"
android:layout_width="37dp"
android:layout_height="36dp"
app:layout_constraintBottom_toBottomOf="@+id/Cardview_MakeText"
app:layout_constraintEnd_toStartOf="@+id/Cardview_MakeText"
app:layout_constraintHorizontal_bias="0.974"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/Cardview_MakeText"
app:layout_constraintVertical_bias="0.444"
app:srcCompat="@drawable/ic_call_icon_final" />
<TextView
android:id="@+id/cardview_Contact_Id"
android:layout_width="23dp"
android:layout_height="15dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/CardView_Name"
app:layout_constraintEnd_toStartOf="@+id/Cardview_delete"
app:layout_constraintHorizontal_bias="0.469"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
XML 布局:MainActivity
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_background"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/activity_rounded_bg"
android:layout_marginTop="50dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="true"
android:paddingHorizontal="0dp"
android:paddingTop="10dp"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="67dp"
tools:listitem="@layout/cardview_contact_item">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
<ImageButton
android:id="@+id/btnAddContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/ic_add_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
这是创建数组列表的 MainActivity
。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
//widgets
public ImageButton eAddContact;
RecyclerView recyclerView;
DatabaseHelper myDB;
ArrayList<String> Contact_id, Contact_Name, Contact_Number;
CustomAdapter customAdapter;
Button btnEnterContact;
private FusedLocationProviderClient fusedLocationProviderClient;
//Google's api for location services.
//private final int REQUEST_CHECK_CODE=8989;
private LocationSettingsRequest.Builder builder;
private String mLatitude,mLongitude;
private static final int REQUEST_SMS = 0;
private static final int REQUEST_LOCATION = 1;
private static final int REQUEST_CALL =2;
Intent mIntent;
LocationManager locationManager;
LocationRequest locationRequest;
LocationCallback locationCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//permissions
if(ContextCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS)!=PackageManager.PERMISSION_GRANTED)
{
//if permission is not granted then check if user has denied
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.SEND_SMS)){
}else
{
//popup for asking permission
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},REQUEST_SMS);
}
}
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED)
{
//if permission is not granted then check if user has denied
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_FINE_LOCATION)){
}else
{
//popup for asking permission
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION);
}
}
if(ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED)
{
//if permission is not granted then check if user has denied
if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CALL_PHONE)){
}else
{
//popup for asking permission
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CALL_PHONE},REQUEST_CALL);
}
}
eAddContact = findViewById(R.id.btnAddContact);
eAddContact.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick:opening dialog");
Dialog_AddContact dialog = new Dialog_AddContact();
dialog.show(getSupportFragmentManager(), "Add Contact Dialog");
}
});
//Toast.makeText(getApplicationContext(),"@#",Toast.LENGTH_SHORT).show();
myDB = new DatabaseHelper(MainActivity.this);
Contact_id = new ArrayList<>();
Contact_Name = new ArrayList<>();
Contact_Number = new ArrayList<>();
recyclerView = findViewById(R.id.RecyclerView);
Cursor cursor= myDB.getEveryone();
customAdapter = new CustomAdapter(MainActivity.this, Contact_id, Contact_Name, Contact_Number,mLatitude,mLongitude);
//set all the properties of LocationRequest
locationRequest = new LocationRequest();
//how often does location check occur
locationRequest.setInterval(1000*30);
locationRequest.setFastestInterval(1000*50);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
//Display cardview data
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
customAdapter.notifyDataSetChanged();
//update gps data
updateGPS();
storeDataInArrays();
/*
ImageView mDelete;
mDelete = findViewById(R.id.Cardview_delete);
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
customAdapter.notifyDataSetChanged();
}
});
*/
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//will check requestCode
switch(requestCode)
{
case REQUEST_SMS:
{
//check if length of grantResults is greater than 0 and equal to PERMISSION_GRANTED
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this,"SMS Permission Granted",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this,"SMS Permission Denied",Toast.LENGTH_LONG).show();
}
}
case REQUEST_LOCATION:
{
//check if length of grantResults is greater than 0 and equal to PERMISSION_GRANTED
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this,"Location Permission Granted",Toast.LENGTH_LONG).show();
updateGPS();
}
else
{
Toast.makeText(this,"Location Permission Denied",Toast.LENGTH_LONG).show();
}
}
case REQUEST_CALL:
{
//check if length of grantResults is greater than 0 and equal to PERMISSION_GRANTED
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this,"Call Permission Granted",Toast.LENGTH_LONG).show();
updateGPS();
}
else
{
Toast.makeText(this,"Call Permission Denied",Toast.LENGTH_LONG).show();
}
}
}//switch
}
private void updateGPS(){
//get permissions from the user to track GPS
//get current location
//update string
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MainActivity.this);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
//user gave the permissions
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
//we got permissions. put the values of location.
updateLocation(location);
}
});
}
else{
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION);
}
}
}
private void updateLocation(Location location) {
//update the location of the person
mLatitude = String.valueOf(location.getLatitude());
mLongitude = String.valueOf(location.getLongitude());
Toast.makeText(this,"Latitude = "+mLatitude,Toast.LENGTH_SHORT).show();
Toast.makeText(this,"Longitude = "+mLongitude,Toast.LENGTH_SHORT).show();
Cursor cursor= myDB.getEveryone();
recyclerView.setAdapter(new CustomAdapter(MainActivity.this, Contact_id, Contact_Name, Contact_Number,mLatitude,mLongitude));
recyclerView.invalidate();
}
void storeDataInArrays() {
customAdapter.notifyDataSetChanged();
Contact_id.clear();
Contact_Name.clear();
Contact_Number.clear();
Cursor cursor = myDB.getEveryone();
if (cursor.getCount() == 0) {
//Add blank page
} else {
while (cursor.moveToNext()) {
Contact_id.add(cursor.getString(0));
Contact_Name.add(cursor.getString(1));
Contact_Number.add(cursor.getString(2));
}
}
recyclerView.setAdapter(new CustomAdapter(MainActivity.this, Contact_id, Contact_Name, Contact_Number,mLatitude,mLongitude));
customAdapter.notifyDataSetChanged();
}
public void removeItem(int position){
Contact_id.remove(true);
storeDataInArrays();
customAdapter.notifyDataSetChanged();
}
//public void onRequestPermissionResult(int requestCOde,String permissions[],int[] grantResults){}//method
public void onLocationChanged(Location location) {
}
public void onProviderDisabled(String provider) {
Log.d("Latitude","disable");
}
public void onProviderEnabled(String provider) {
Log.d("Latitude","enable");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Latitude","status");
}
}
我好像做错了什么? 非常感谢任何帮助。
我不太确定,但更新 ArrayList(s) 应该可以。
mDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//int id= Integer.parseInt(Contact_id.getText.toString());
int contactId = Integer.parseInt(Contact_id_txt.getText().toString());
Toast.makeText(context, "int id ="+contactId+"Contact id ="+Contact_id, Toast.LENGTH_SHORT).show();
DatabaseHelper databaseHelper = new DatabaseHelper(context);
boolean success = databaseHelper.deleteOne(contactId);
Contact_id.remove(Integer.valueOf(contactId));
Toast.makeText(context, "Contact Deleted", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
我认为 Contact_Name 和 Contact_number 可能也需要更新,但这取决于如何MainActivity 代码会处理它。