RecyclerView 中的项目位置仅在拖动列表时发生变化,同时也是错误的
Item position in RecyclerView only changing when dragging list, while being wrong too
我正在使用一个 livedata>,它被用来 poblate 一个回收器视图,然后我用它来 select 该列表中的一个项目,并将它传递给另一个 activity .
Said recyclerview can be here seen in action:
您可能会看到,当我单击“Ansiedad”项时,我得到了另一个与 selected 项不匹配的项“Artrosis de codo”。只要我不在 recyclerview 周围拖来拖去,无论我在列表上的哪个位置触摸,该项目都会得到 selected。当我在列表中向上或向下移动时,项目会发生变化,但我从未设法使其与实际 selected 项目相匹配。似乎总是 select 无需向下滚动即可看到 recyclerview 上的最后一项。我推测这是由于在过滤时创建了一个新的 LiveData>,但我还没有找到任何关于它的东西。
我已经遇到这个问题好几天了,我没有找到任何关于如何解决这个问题的好信息,所以我认为最好问一下。
这里是 类 连接到那个 recyclerview 的:
Activity:
package com.gmproxy.pastilarma;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SearchView;
import android.widget.Toast;
import com.gmproxy.Adapters.PathologyListAdapter;
import com.gmproxy.DAO.DatabaseHelper;
import com.gmproxy.DAO.PathologyDAO;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Util.PathologyViewModel;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PathologiesSearchScreen extends AppCompatActivity {
private PathologyViewModel viewModel;
SearchView searchView;
RecyclerView recyclerView;
Pathology pathology;
PathologyListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pathology_search_list);
searchView = findViewById(R.id.SearchView);
recyclerView = findViewById(R.id.recyclerview);
adapter = new PathologyListAdapter(new PathologyListAdapter.UserDiff());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
viewModel = new ViewModelProvider(this).get(PathologyViewModel.class);
viewModel.pathologies.observe(this, adapter::submitList);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
viewModel.setFilter(searchView.getQuery().toString());
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
long start;
start = System.currentTimeMillis();
if ((newText.length() > 3) && (System.currentTimeMillis() - start > 500)) {
viewModel.setFilter(searchView.getQuery().toString());
}
return false;
}
});
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(@NonNull @NotNull RecyclerView rv, @NonNull @NotNull MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_SETTLING
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_DRAGGING){
pathology = getSelectedPathology();
Log.println(Log.INFO, "PathologyTest", pathology.toString());
final CharSequence[] options = {"Si", "No"};
AlertDialog.Builder builder = new AlertDialog.Builder(PathologiesSearchScreen.this);
builder.setTitle("¿Añadir la patología " + pathology.getPathologyName() + "?");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Si")) {
Toast.makeText(PathologiesSearchScreen.this, "Has añadido la patología " + pathology.getPathologyName() + ".", Toast.LENGTH_SHORT).show();
Intent mainAct = new Intent(PathologiesSearchScreen.this, UserAddScreen.class);
mainAct.putExtra("path", pathology);
int i = 1;
mainAct.putExtra("path-record",i);
startActivity(mainAct);
} else if (options[item].equals("No")) {
dialog.dismiss();
}
}
});
builder.show();
}
return false;
}
@Override
public void onTouchEvent(@NonNull @NotNull RecyclerView rv, @NonNull @NotNull MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
}
public Pathology getSelectedPathology(){
Pathology path = adapter.getCurrentObject();
Log.println(Log.INFO, "PathologyTest ID", path.toString());
return path;
}
}
列表适配器:
package com.gmproxy.Adapters;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.LiveData;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.pastilarma.PathologiesSearchScreen;
import com.gmproxy.pastilarma.UserAddScreen;
import java.util.List;
public class PathologyListAdapter extends ListAdapter<Pathology, PathologyViewHolder> {
private int positionF;
private Pathology path;
public PathologyListAdapter(@NonNull DiffUtil.ItemCallback<Pathology> diffCallback) {
super(diffCallback);
}
@Override
public PathologyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return PathologyViewHolder.create(parent);
}
@Override
public void onBindViewHolder(PathologyViewHolder holder, int position) {
positionF = position;
Pathology current = getItem(position);
path = current;
holder.bind(current.getPathologyName());
}
public Pathology getCurrentObject(){
path = getItem(positionF);
return path;
}
public int getPositionF(){
return positionF;
}
public static class UserDiff extends DiffUtil.ItemCallback<Pathology> {
@Override
public boolean areItemsTheSame(@NonNull Pathology oldItem, @NonNull Pathology newItem) {
return oldItem == newItem;
}
@Override
public boolean areContentsTheSame(@NonNull Pathology oldItem, @NonNull Pathology newItem) {
return oldItem.getPathologyName().equals(newItem.getPathologyName());
}
}
}
ViewHolder:
package com.gmproxy.Adapters;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import com.gmproxy.DAO.PathologyDAO;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.pastilarma.PathologiesSearchScreen;
import com.gmproxy.pastilarma.R;
import java.nio.file.Path;
public class PathologyViewHolder extends RecyclerView.ViewHolder {
public final TextView objItemView;
public PathologyViewHolder(View itemView) {
super(itemView);
objItemView = itemView.findViewById(R.id.textView);
}
public void bind(String current) {
objItemView.setText(current);
}
static PathologyViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.pathologies_item, parent, false);
return new PathologyViewHolder(view);
}
}
视图模型:
package com.gmproxy.Util;
import android.app.Application;
import android.widget.Filter;
import android.widget.Filterable;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import com.gmproxy.DAO.PathologyRepository;
import com.gmproxy.Entities.Pathology;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class PathologyViewModel extends AndroidViewModel {
private PathologyRepository repository;
public LiveData<List<Pathology>> pathologies;
public MutableLiveData<String> filteredList = new MutableLiveData<>();
public PathologyViewModel(Application application) {
super(application);
repository = new PathologyRepository(application);
pathologies = Transformations.switchMap(filteredList, (input) -> {
if(input == null || input.equals("")){
return repository.getAllObjects();
} else {
return repository.filter(input);
}
});
}
public void setFilter(String query){
filteredList.setValue(query);
}
public Pathology ObtainById(String id) {return repository.obtainById(id); }
public int getDataCount() { return repository.getDataCount();}
public void insert(Pathology obj) { repository.insertObject(obj); }
public void delete(Pathology obj) { repository.deleteObject(obj); }
}
实体库:
package com.gmproxy.DAO;
import android.app.Application;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Entities.User;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class PathologyRepository {
private PathologyDAO concerningDao;
private LiveData<List<Pathology>> pathologyList;
public PathologyRepository(Application application) {
DatabaseHelper db = DatabaseHelper.getDatabase(application);
concerningDao = db.pathologyDao();
pathologyList = concerningDao.getAllObjects();
}
public LiveData<List<Pathology>> getAllObjects() {
return concerningDao.getAllObjects();
}
void insertAllObjects(List<Pathology> objectsList) {
DatabaseHelper.databaseWriteExecutor.execute(() ->{
concerningDao.insertAllObjects(objectsList);
});
}
public void insertObject(Pathology obj){
DatabaseHelper.databaseWriteExecutor.execute(() ->{
concerningDao.insertObject(obj);
});
}
public Pathology obtainById(String id){
try{
return new ObjectAsyncTask(concerningDao).execute(id).get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public int getDataCount() { return concerningDao.getDataCount(); }
public void deleteObject(Pathology obj) {
concerningDao.delete(obj);
}
public LiveData<List<Pathology>> filter(String input){
try{
return new FilterNoteAsyncTask(concerningDao).execute(input).get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
private static class FilterNoteAsyncTask extends AsyncTask<String, Void, LiveData<List<Pathology>>> {
private PathologyDAO pathologyDAO;
private FilterNoteAsyncTask(PathologyDAO pathologyDAO) {
this.pathologyDAO = pathologyDAO;
}
@Override
protected LiveData<List<Pathology>> doInBackground(String... strings) {
return pathologyDAO.filterText(strings[0]);
}
}
private static class ObjectAsyncTask extends AsyncTask<String, Void, Pathology>{
private PathologyDAO pathologyDAO;
private ObjectAsyncTask(PathologyDAO pathologyDAO) { this.pathologyDAO = pathologyDAO; }
@Override
protected Pathology doInBackground(String...strings) {
int id = Integer.parseInt(strings.toString());
return pathologyDAO.findObjectById(id);
}
}
}
DAO:
package com.gmproxy.DAO;
import androidx.lifecycle.LiveData;
import androidx.room.*;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Entities.User;
import java.util.List;
@Dao
public interface PathologyDAO {
@Query("SELECT * FROM condiciones")
LiveData<List<Pathology>> getAllObjects();
//This will come in handy for getting all those pathologies, will need to get them on a for loop since I'm not completely sure
//that the query will handle int[]
@Query("SELECT id_condiciones FROM condiciones WHERE id_condiciones LIKE :id_condiciones")
int getPathologiesForUser(int id_condiciones);
@Query("SELECT nombreCondicion FROM condiciones WHERE nombreCondicion LIKE :pathologyName")
String getPathologiesForName(String pathologyName);
@Query("SELECT * FROM condiciones WHERE nombreCondicion LIKE :pathologyName")
Pathology getPathologiesCompleteForName(String pathologyName);
@Query("SELECT * FROM condiciones WHERE id_condiciones=:id")
Pathology findObjectById(int id);
@Query("SELECT COUNT(id_condiciones) FROM condiciones")
int getDataCount();
@Query("SELECT * FROM condiciones WHERE nombreCondicion LIKE :filter || '%'")
LiveData<List<Pathology>> filterText(String filter);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAllObjects(List<Pathology> listObjects);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertObject(Pathology object);
@Update
void updateObject(Pathology object);
@Delete
void delete(Pathology obj);
}
问题是您没有传递您正在点击的项目,所以您现在不能在点击的地方,而不是这个:
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(@NonNull @NotNull RecyclerView rv, @NonNull @NotNull MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_SETTLING
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_DRAGGING){
pathology = getSelectedPathology();
Log.println(Log.INFO, "PathologyTest", pathology.toString());
final CharSequence[] options = {"Si", "No"};
AlertDialog.Builder builder = new AlertDialog.Builder(PathologiesSearchScreen.this);
builder.setTitle("¿Añadir la patología " + pathology.getPathologyName() + "?");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Si")) {
Toast.makeText(PathologiesSearchScreen.this, "Has añadido la patología " + pathology.getPathologyName() + ".", Toast.LENGTH_SHORT).show();
Intent mainAct = new Intent(PathologiesSearchScreen.this, UserAddScreen.class);
mainAct.putExtra("path", pathology);
int i = 1;
mainAct.putExtra("path-record",i);
startActivity(mainAct);
} else if (options[item].equals("No")) {
dialog.dismiss();
}
}
});
builder.show();
}
return false;
}
做这样的事情:
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
pathology = getSelectedPathology(position);
// rest of your code
}
@Override public void onLongItemClick(View view, int position) {
// do whatever
}
}));
public Pathology getSelectedPathology(int position){
Pathology path = adapter.getCurrentObject(position);
Log.println(Log.INFO, "PathologyTest ID", path.toString());
return path;
}
现在您在适配器中的 getCurrentObject
方法获取点击的项目位置
public Pathology getCurrentObject(int clickPosition){
path = getItem(clickPosition);
return path;
}
您遇到的问题似乎是您的适配器存储了最后绑定的项目,而不是您单击的项目。这就是为什么Adapter的大部分方法都采用“position”参数的原因。
也许你可以在 Adapter 中设置一个 IteractionListener,稍后传递给 ViewHolder(或由它以其他方式访问),然后将 OnClick 监听器添加到 TextView。
我正在使用一个 livedata>,它被用来 poblate 一个回收器视图,然后我用它来 select 该列表中的一个项目,并将它传递给另一个 activity .
Said recyclerview can be here seen in action:
您可能会看到,当我单击“Ansiedad”项时,我得到了另一个与 selected 项不匹配的项“Artrosis de codo”。只要我不在 recyclerview 周围拖来拖去,无论我在列表上的哪个位置触摸,该项目都会得到 selected。当我在列表中向上或向下移动时,项目会发生变化,但我从未设法使其与实际 selected 项目相匹配。似乎总是 select 无需向下滚动即可看到 recyclerview 上的最后一项。我推测这是由于在过滤时创建了一个新的 LiveData>,但我还没有找到任何关于它的东西。
我已经遇到这个问题好几天了,我没有找到任何关于如何解决这个问题的好信息,所以我认为最好问一下。
这里是 类 连接到那个 recyclerview 的:
Activity:
package com.gmproxy.pastilarma;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SearchView;
import android.widget.Toast;
import com.gmproxy.Adapters.PathologyListAdapter;
import com.gmproxy.DAO.DatabaseHelper;
import com.gmproxy.DAO.PathologyDAO;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Util.PathologyViewModel;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PathologiesSearchScreen extends AppCompatActivity {
private PathologyViewModel viewModel;
SearchView searchView;
RecyclerView recyclerView;
Pathology pathology;
PathologyListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pathology_search_list);
searchView = findViewById(R.id.SearchView);
recyclerView = findViewById(R.id.recyclerview);
adapter = new PathologyListAdapter(new PathologyListAdapter.UserDiff());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
viewModel = new ViewModelProvider(this).get(PathologyViewModel.class);
viewModel.pathologies.observe(this, adapter::submitList);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
viewModel.setFilter(searchView.getQuery().toString());
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
long start;
start = System.currentTimeMillis();
if ((newText.length() > 3) && (System.currentTimeMillis() - start > 500)) {
viewModel.setFilter(searchView.getQuery().toString());
}
return false;
}
});
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(@NonNull @NotNull RecyclerView rv, @NonNull @NotNull MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_SETTLING
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_DRAGGING){
pathology = getSelectedPathology();
Log.println(Log.INFO, "PathologyTest", pathology.toString());
final CharSequence[] options = {"Si", "No"};
AlertDialog.Builder builder = new AlertDialog.Builder(PathologiesSearchScreen.this);
builder.setTitle("¿Añadir la patología " + pathology.getPathologyName() + "?");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Si")) {
Toast.makeText(PathologiesSearchScreen.this, "Has añadido la patología " + pathology.getPathologyName() + ".", Toast.LENGTH_SHORT).show();
Intent mainAct = new Intent(PathologiesSearchScreen.this, UserAddScreen.class);
mainAct.putExtra("path", pathology);
int i = 1;
mainAct.putExtra("path-record",i);
startActivity(mainAct);
} else if (options[item].equals("No")) {
dialog.dismiss();
}
}
});
builder.show();
}
return false;
}
@Override
public void onTouchEvent(@NonNull @NotNull RecyclerView rv, @NonNull @NotNull MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
}
public Pathology getSelectedPathology(){
Pathology path = adapter.getCurrentObject();
Log.println(Log.INFO, "PathologyTest ID", path.toString());
return path;
}
}
列表适配器:
package com.gmproxy.Adapters;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.LiveData;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.pastilarma.PathologiesSearchScreen;
import com.gmproxy.pastilarma.UserAddScreen;
import java.util.List;
public class PathologyListAdapter extends ListAdapter<Pathology, PathologyViewHolder> {
private int positionF;
private Pathology path;
public PathologyListAdapter(@NonNull DiffUtil.ItemCallback<Pathology> diffCallback) {
super(diffCallback);
}
@Override
public PathologyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return PathologyViewHolder.create(parent);
}
@Override
public void onBindViewHolder(PathologyViewHolder holder, int position) {
positionF = position;
Pathology current = getItem(position);
path = current;
holder.bind(current.getPathologyName());
}
public Pathology getCurrentObject(){
path = getItem(positionF);
return path;
}
public int getPositionF(){
return positionF;
}
public static class UserDiff extends DiffUtil.ItemCallback<Pathology> {
@Override
public boolean areItemsTheSame(@NonNull Pathology oldItem, @NonNull Pathology newItem) {
return oldItem == newItem;
}
@Override
public boolean areContentsTheSame(@NonNull Pathology oldItem, @NonNull Pathology newItem) {
return oldItem.getPathologyName().equals(newItem.getPathologyName());
}
}
}
ViewHolder:
package com.gmproxy.Adapters;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import com.gmproxy.DAO.PathologyDAO;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.pastilarma.PathologiesSearchScreen;
import com.gmproxy.pastilarma.R;
import java.nio.file.Path;
public class PathologyViewHolder extends RecyclerView.ViewHolder {
public final TextView objItemView;
public PathologyViewHolder(View itemView) {
super(itemView);
objItemView = itemView.findViewById(R.id.textView);
}
public void bind(String current) {
objItemView.setText(current);
}
static PathologyViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.pathologies_item, parent, false);
return new PathologyViewHolder(view);
}
}
视图模型:
package com.gmproxy.Util;
import android.app.Application;
import android.widget.Filter;
import android.widget.Filterable;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import com.gmproxy.DAO.PathologyRepository;
import com.gmproxy.Entities.Pathology;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class PathologyViewModel extends AndroidViewModel {
private PathologyRepository repository;
public LiveData<List<Pathology>> pathologies;
public MutableLiveData<String> filteredList = new MutableLiveData<>();
public PathologyViewModel(Application application) {
super(application);
repository = new PathologyRepository(application);
pathologies = Transformations.switchMap(filteredList, (input) -> {
if(input == null || input.equals("")){
return repository.getAllObjects();
} else {
return repository.filter(input);
}
});
}
public void setFilter(String query){
filteredList.setValue(query);
}
public Pathology ObtainById(String id) {return repository.obtainById(id); }
public int getDataCount() { return repository.getDataCount();}
public void insert(Pathology obj) { repository.insertObject(obj); }
public void delete(Pathology obj) { repository.deleteObject(obj); }
}
实体库:
package com.gmproxy.DAO;
import android.app.Application;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Entities.User;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class PathologyRepository {
private PathologyDAO concerningDao;
private LiveData<List<Pathology>> pathologyList;
public PathologyRepository(Application application) {
DatabaseHelper db = DatabaseHelper.getDatabase(application);
concerningDao = db.pathologyDao();
pathologyList = concerningDao.getAllObjects();
}
public LiveData<List<Pathology>> getAllObjects() {
return concerningDao.getAllObjects();
}
void insertAllObjects(List<Pathology> objectsList) {
DatabaseHelper.databaseWriteExecutor.execute(() ->{
concerningDao.insertAllObjects(objectsList);
});
}
public void insertObject(Pathology obj){
DatabaseHelper.databaseWriteExecutor.execute(() ->{
concerningDao.insertObject(obj);
});
}
public Pathology obtainById(String id){
try{
return new ObjectAsyncTask(concerningDao).execute(id).get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public int getDataCount() { return concerningDao.getDataCount(); }
public void deleteObject(Pathology obj) {
concerningDao.delete(obj);
}
public LiveData<List<Pathology>> filter(String input){
try{
return new FilterNoteAsyncTask(concerningDao).execute(input).get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
private static class FilterNoteAsyncTask extends AsyncTask<String, Void, LiveData<List<Pathology>>> {
private PathologyDAO pathologyDAO;
private FilterNoteAsyncTask(PathologyDAO pathologyDAO) {
this.pathologyDAO = pathologyDAO;
}
@Override
protected LiveData<List<Pathology>> doInBackground(String... strings) {
return pathologyDAO.filterText(strings[0]);
}
}
private static class ObjectAsyncTask extends AsyncTask<String, Void, Pathology>{
private PathologyDAO pathologyDAO;
private ObjectAsyncTask(PathologyDAO pathologyDAO) { this.pathologyDAO = pathologyDAO; }
@Override
protected Pathology doInBackground(String...strings) {
int id = Integer.parseInt(strings.toString());
return pathologyDAO.findObjectById(id);
}
}
}
DAO:
package com.gmproxy.DAO;
import androidx.lifecycle.LiveData;
import androidx.room.*;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Entities.User;
import java.util.List;
@Dao
public interface PathologyDAO {
@Query("SELECT * FROM condiciones")
LiveData<List<Pathology>> getAllObjects();
//This will come in handy for getting all those pathologies, will need to get them on a for loop since I'm not completely sure
//that the query will handle int[]
@Query("SELECT id_condiciones FROM condiciones WHERE id_condiciones LIKE :id_condiciones")
int getPathologiesForUser(int id_condiciones);
@Query("SELECT nombreCondicion FROM condiciones WHERE nombreCondicion LIKE :pathologyName")
String getPathologiesForName(String pathologyName);
@Query("SELECT * FROM condiciones WHERE nombreCondicion LIKE :pathologyName")
Pathology getPathologiesCompleteForName(String pathologyName);
@Query("SELECT * FROM condiciones WHERE id_condiciones=:id")
Pathology findObjectById(int id);
@Query("SELECT COUNT(id_condiciones) FROM condiciones")
int getDataCount();
@Query("SELECT * FROM condiciones WHERE nombreCondicion LIKE :filter || '%'")
LiveData<List<Pathology>> filterText(String filter);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAllObjects(List<Pathology> listObjects);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertObject(Pathology object);
@Update
void updateObject(Pathology object);
@Delete
void delete(Pathology obj);
}
问题是您没有传递您正在点击的项目,所以您现在不能在点击的地方,而不是这个:
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(@NonNull @NotNull RecyclerView rv, @NonNull @NotNull MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_SETTLING
&& rv.getScrollState() != RecyclerView.SCROLL_STATE_DRAGGING){
pathology = getSelectedPathology();
Log.println(Log.INFO, "PathologyTest", pathology.toString());
final CharSequence[] options = {"Si", "No"};
AlertDialog.Builder builder = new AlertDialog.Builder(PathologiesSearchScreen.this);
builder.setTitle("¿Añadir la patología " + pathology.getPathologyName() + "?");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Si")) {
Toast.makeText(PathologiesSearchScreen.this, "Has añadido la patología " + pathology.getPathologyName() + ".", Toast.LENGTH_SHORT).show();
Intent mainAct = new Intent(PathologiesSearchScreen.this, UserAddScreen.class);
mainAct.putExtra("path", pathology);
int i = 1;
mainAct.putExtra("path-record",i);
startActivity(mainAct);
} else if (options[item].equals("No")) {
dialog.dismiss();
}
}
});
builder.show();
}
return false;
}
做这样的事情:
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
pathology = getSelectedPathology(position);
// rest of your code
}
@Override public void onLongItemClick(View view, int position) {
// do whatever
}
}));
public Pathology getSelectedPathology(int position){
Pathology path = adapter.getCurrentObject(position);
Log.println(Log.INFO, "PathologyTest ID", path.toString());
return path;
}
现在您在适配器中的 getCurrentObject
方法获取点击的项目位置
public Pathology getCurrentObject(int clickPosition){
path = getItem(clickPosition);
return path;
}
您遇到的问题似乎是您的适配器存储了最后绑定的项目,而不是您单击的项目。这就是为什么Adapter的大部分方法都采用“position”参数的原因。
也许你可以在 Adapter 中设置一个 IteractionListener,稍后传递给 ViewHolder(或由它以其他方式访问),然后将 OnClick 监听器添加到 TextView。