5. Удаление пункта списка
Теперь необходимо добавить обработку нажатия на кнопку "Х" в пункте списка.
Добавим интерфейс для слушателя нажатия на кнопку удаления пункта списка. В метод передается позиция пункта списка для того, чтобы определить - какой элемент коллекции с контактами нужно удалить.
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {
public interface DeleteItemListener {
void onDeleteItem(int position);
}
...
}
Добавим поле для объекта DeleteItemListener
, добавим еще один параметр конструктора
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {
public interface DeleteItemListener {
void onDeleteItem(int position);
}
private final LayoutInflater inflater;
private final List<Contact> list;
private DeleteItemListener listener;
private static final int EMPTY_LIST_TYPE = 0;
private static final int NON_EMPTY_LIST_TYPE = 1;
public ContactsAdapter(Context context, List<Contact> users, DeleteItemListener listener) {
this.inflater = LayoutInflater.from(context);
this.list = users;
this.listener = listener;
}
...
}
Вернемся в MainActivity.java
. Добавим реализацию интерфейса, напишем логику метода onClick()
, а также исправим код для создания объекта адаптера.
public class MainActivity extends AppCompatActivity implements ContactsAdapter.DeleteItemListener {
private List<Contact> list = new ArrayList<>();
private ContactsAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mRecyclerView = findViewById(R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new ContactsAdapter(getApplicationContext(), list, this);
mRecyclerView.setAdapter(adapter);
}
@Override
public void onDeleteItem(int position) {
list.remove(position);
adapter.notifyDataSetChanged();
}
}
Изменим код для ContactHolder
. Добавим ссылки на кнопку удаления, добавим поле для объекта DeleteItemListener
. При создании ContactHolder
будем получать ссылку на объета DeleteItemListener
. Далее, создаем слушатель нажатия на кнопку "X", в котором мы будем вызывать метод onDeleteItem()
у объекта MainActivity
.
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {
...
static class ContactHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView image;
TextView name;
TextView email;
TextView phone;
ImageButton deleteButton;
DeleteItemListener listener;
public ContactHolder(@NonNull View itemView, DeleteItemListener listener) {
super(itemView);
image = itemView.findViewById(R.id.contact_image);
name = itemView.findViewById(R.id.name);
email = itemView.findViewById(R.id.email);
phone = itemView.findViewById(R.id.phone);
deleteButton = itemView.findViewById(R.id.clearButton);
this.listener = listener;
if ((int) itemView.getTag() == NON_EMPTY_LIST_TYPE) {
deleteButton.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
listener.onDeleteItem(getAdapterPosition());
}
}
}
Изменим код метода onCreateViewHolder()
, при создании объекта ContactHolder
, передадим ссылку на объект слушателя. В нашем случае - ссылку на объект MainActyivity
, который реализует слушатель удаления пункта списка.
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {
@NonNull
@Override
public ContactHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
if (viewType == EMPTY_LIST_TYPE) {
view = inflater.inflate(R.layout.list_no_items, parent, false);
view.setTag(EMPTY_LIST_TYPE);
} else {
view = inflater.inflate(R.layout.list_contact, parent, false);
view.setTag(NON_EMPTY_LIST_TYPE);
}
return new ContactHolder(view, listener);
}
}
Ниже приведены итоговые листинги классов.
public class MainActivity extends AppCompatActivity implements ContactsAdapter.DeleteItemListener {
private static final int ADD_CONTACT_REQUEST_CODE = 5556;
private RecyclerView mRecyclerView;
private FloatingActionButton mAddContactButton;
private List<Contact> list = new ArrayList<>();
private ContactsAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setWindow();
mRecyclerView = findViewById(R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new ContactsAdapter(getApplicationContext(), list, this);
mRecyclerView.setAdapter(adapter);
mAddContactButton = findViewById(R.id.fab);
mAddContactButton.setOnClickListener(v -> {
Intent i = new Intent(this, AddContactActivity.class);
startActivityForResult(i, ADD_CONTACT_REQUEST_CODE);
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_CONTACT_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
String name = data.getStringExtra(Intent.EXTRA_USER);
String email = data.getStringExtra(Intent.EXTRA_EMAIL);
String phone = data.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Uri uri = Uri.parse(data.getStringExtra(Intent.EXTRA_ORIGINATING_URI));
list.add(new Contact(name, email, phone, uri));
adapter.notifyDataSetChanged();
}
}
private void setWindow() {
// Метод устанавливает StatusBar в цвет фона
Window window = this.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(getColor(R.color.activity_background));
View decor = getWindow().getDecorView();
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static final String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public void verifyStoragePermissions() {
// Проверяем наличие разрешения на запись во внешнее хранилище
int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// Запрашиваем разрешение у пользователя
ActivityCompat.requestPermissions(
this,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
@Override
protected void onStart() {
super.onStart();
verifyStoragePermissions();
}
@Override
public void onDeleteItem(int position) {
list.remove(position);
adapter.notifyDataSetChanged();
}
}
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactHolder> {
public interface DeleteItemListener {
void onDeleteItem(int position);
}
private final LayoutInflater inflater;
private final List<Contact> list;
private DeleteItemListener listener;
private static final int EMPTY_LIST_TYPE = 0;
private static final int NON_EMPTY_LIST_TYPE = 1;
public ContactsAdapter(Context context, List<Contact> users, DeleteItemListener listener) {
this.inflater = LayoutInflater.from(context);
this.list = users;
this.listener = listener;
}
@Override
public int getItemViewType(int position) {
return list.isEmpty() ? EMPTY_LIST_TYPE : NON_EMPTY_LIST_TYPE;
}
@NonNull
@Override
public ContactHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
if (viewType == EMPTY_LIST_TYPE) {
view = inflater.inflate(R.layout.list_no_items, parent, false);
view.setTag(EMPTY_LIST_TYPE);
} else {
view = inflater.inflate(R.layout.list_contact, parent, false);
view.setTag(NON_EMPTY_LIST_TYPE);
}
return new ContactHolder(view, listener);
}
@Override
public void onBindViewHolder(@NonNull ContactHolder holder, int position) {
if (getItemViewType(position) == EMPTY_LIST_TYPE)
return;
Contact contact = list.get(position);
holder.image.setImageURI(contact.getUri());
holder.name.setText(contact.getName());
holder.email.setText(contact.getEmail());
holder.phone.setText(contact.getPhone());
}
@Override
public int getItemCount() {
return Math.max(list.size(), 1);
}
static class ContactHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView image;
TextView name;
TextView email;
TextView phone;
ImageButton deleteButton;
DeleteItemListener listener;
public ContactHolder(@NonNull View itemView, DeleteItemListener listener) {
super(itemView);
image = itemView.findViewById(R.id.contact_image);
name = itemView.findViewById(R.id.name);
email = itemView.findViewById(R.id.email);
phone = itemView.findViewById(R.id.phone);
deleteButton = itemView.findViewById(R.id.clearButton);
this.listener = listener;
if ((int) itemView.getTag() == NON_EMPTY_LIST_TYPE) {
deleteButton.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
listener.onDeleteItem(getAdapterPosition());
}
}
}
public class AddContactActivity extends AppCompatActivity {
private ImageView mContactImage;
private Uri mContactImageUri;
private static final int IMAGE_CAPTURE_REQUEST_CODE = 7777;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_contact);
setWindow();
mContactImage = findViewById(R.id.profile_image);
EditText nameEditText = findViewById(R.id.name_et);
EditText EmailEditText = findViewById(R.id.email_et);
EditText PhoneEditText = findViewById(R.id.phone_et);
Button addContactButton = findViewById(R.id.button_add);
addContactButton.setOnClickListener(v -> {
if (mContactImageUri == null) {
Toast.makeText(this, "Contact image not set!", Toast.LENGTH_SHORT).show();
return;
}
String name = nameEditText.getText().toString();
String email = EmailEditText.getText().toString();
String phone = PhoneEditText.getText().toString();
Intent i = new Intent();
i.putExtra(Intent.EXTRA_USER, name);
i.putExtra(Intent.EXTRA_EMAIL, email);
i.putExtra(Intent.EXTRA_PHONE_NUMBER, phone);
i.putExtra(Intent.EXTRA_ORIGINATING_URI, mContactImageUri.toString());
setResult(RESULT_OK, i);
finish();
});
Button takePhotoButton = findViewById(R.id.button_camera);
takePhotoButton.setOnClickListener(v -> {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
startActivityForResult(takePictureIntent, IMAGE_CAPTURE_REQUEST_CODE);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, "Error while trying to open camera app", Toast.LENGTH_SHORT).show();
}
});
Button cancelButton = findViewById(R.id.button_cancel);
cancelButton.setOnClickListener(v -> onBackPressed());
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_CAPTURE_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
// Меняем ImageView с изображением контакта
mContactImage.setImageBitmap(imageBitmap);
String filename = "contact_" + System.currentTimeMillis() + ".png";
File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), filename);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(outputFile);
imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
// Сохраняем путь к файлу в формате Uri
mContactImageUri = Uri.fromFile(outputFile);
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
setResult(RESULT_CANCELED);
}
private void setWindow() {
// Метод устанавливает StatusBar в цвет фона
Window window = this.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(getColor(R.color.activity_background));
View decor = getWindow().getDecorView();
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
public class Contact {
private String name;
private String email;
private String phone;
private Uri uri;
public Contact(String name, String email, String phone, Uri uri) {
this.name = name;
this.email = email;
this.phone = phone;
this.uri = uri;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Uri getUri() {
return uri;
}
public void setUri(Uri uri) {
this.uri = uri;
}
}
Last updated