获取列表视图的arraylist的原始位置
Posted
技术标签:
【中文标题】获取列表视图的arraylist的原始位置【英文标题】:Getting original position of arraylist for listview 【发布时间】:2021-09-29 23:55:46 【问题描述】:我试图为列表视图创建一个搜索功能,并将意图活动放在结果中。但是,随着搜索结果的出现,位置发生了变化。例如, 原始位置应为 0,1。但是经过搜索,结果将位置转为3,4。 我尝试为此找到许多解决方案,但没有任何帮助。提前致谢!
这里是 homefragment.java
package com.example.testtt;
import androidx.cardview.widget.CardView;
import androidx.fragment.app.Fragment;;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SearchView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
public class HomeFragment extends Fragment implements View.OnClickListener
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState)
View v = inflater.inflate(R.layout.fragment_home, container, false);
//define
RelativeLayout drawerlayouthome;
ListView list;
ListViewAdapter adapter;
SearchView editsearch;
ArrayList<DoaSearchIndex> arrayList = new ArrayList<DoaSearchIndex>();
String[] doasearchindex = getActivity().getResources().getStringArray(R.array.doasearchindex);
//locatelistview
list = v.findViewById(R.id.searchlistview);
list.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
Intent intent;
switch (i)
case 0:
intent = new Intent(getActivity(), firstactivity.class);
startActivity(intent);
getId();
break;
case 1:
intent = new Intent(getActivity(), secondactivity.class);
startActivity(intent);
getId();
break;
list.setVisibility(View.INVISIBLE);
);
for (int i = 0; i < doasearchindex.length; i++)
DoaSearchIndex doaSearchIndex = new DoaSearchIndex(doasearchindex[i]);
arrayList.add(doaSearchIndex);
//pass result to listviewadapter.class
adapter = new ListViewAdapter(this.getActivity(), arrayList);
//binds adapter to listview
list.setAdapter(adapter);
list.setVisibility(View.INVISIBLE);
//locatesearchview
editsearch = v.findViewById(R.id.searchview);
editsearch.setOnQueryTextListener(new SearchView.OnQueryTextListener()
@Override
public boolean onQueryTextSubmit(String query)
return false;
@Override
public boolean onQueryTextChange(String newText)
if(TextUtils.isEmpty(newText))
list.clearTextFilter();
adapter.filter("");
list.setVisibility(View.INVISIBLE);
else
adapter.filter(newText);
list.setVisibility(View.VISIBLE);
return true;
);
drawerlayouthome = v.findViewById(R.id.drawer_layouthome);
drawerlayouthome.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
list.setVisibility(View.INVISIBLE);
editsearch.clearFocus();
);
//definingcardview
CardView test = v.findViewById(R.id.test);
CardView testcard = v.findViewById(R.id.testcard);
//setcardviewlistener
test.setOnClickListener(this);
testcard.setOnClickListener(this);
return v;
@Override
public void onClick(View view)
Intent i ;
switch (view.getId())
case R.id.test:
i = new Intent(getActivity(), test.class);
startActivity(i);
break;
case R.id.testcard:
i = new Intent(getActivity(), testcard.class);
startActivity(i);
break;
和 ListViewAdapter.java
package com.example.testtt;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class ListViewAdapter extends BaseAdapter
//Declare variables first
Context mContext;
LayoutInflater inflater;
private List<DoaSearchIndex> doaSearchIndexList = null;
private ArrayList<DoaSearchIndex> arrayList;
public ListViewAdapter(Context context, List<DoaSearchIndex> doaSearchIndexList)
mContext = context;
this.doaSearchIndexList = doaSearchIndexList;
inflater = LayoutInflater.from(mContext);
this.arrayList = new ArrayList<DoaSearchIndex>();
this.arrayList.addAll(doaSearchIndexList);
public class ViewHolder
TextView name;
@Override
public int getCount()
return doaSearchIndexList.size();
@Override
public DoaSearchIndex getItem(int position)
return doaSearchIndexList.get(position);
@Override
public long getItemId(int position)
return position;
public View getView(final int position, View view, ViewGroup parent)
final ViewHolder holder;
if (view == null)
holder = new ViewHolder();
view = inflater.inflate(R.layout.listview_item, null);
// Locate the TextViews in listview_item.xml
holder.name = (TextView) view.findViewById(R.id.name);
view.setTag(holder);
else
holder = (ViewHolder) view.getTag();
// Set the results into TextViews
holder.name.setText(doaSearchIndexList.get(position).getDoaSearchIndex());
return view;
// Filter Class
public void filter(String charText)
charText = charText.toLowerCase(Locale.getDefault());
doaSearchIndexList.clear();
if (charText.length() == 0)
doaSearchIndexList.addAll(arrayList);
else
for (DoaSearchIndex wp : arrayList)
if (wp.getDoaSearchIndex().toLowerCase(Locale.getDefault()).contains(charText))
doaSearchIndexList.add(wp);
notifyDataSetChanged();
和 DoaSearchIndex.java
public class DoaSearchIndex
private String doaSearchIndex;
private int originalPosition;
public DoaSearchIndex(String doaSearchIndex)
this.doaSearchIndex = doaSearchIndex;
public String getDoaSearchIndex()
return this.doaSearchIndex;
private int getPosition()
return this.originalPosition;
【问题讨论】:
请尝试在 ViewHolder 类中使用位置变量,并在从 getview 创建对象时对其进行更新...然后尝试通过在 getview 中使用 viewholder 实例来使用该位置 ....如果您需要此点击然后你可以在视图中使用 setag 和 gettag ..可以帮助你 您在代码中的什么位置记录这些位置? @Ghanshyam 你能举个例子吗? 你能试试我的答案吗?如果您跟随,即使您在 recyclerView 中搜索特定项目,您的位置也会被记住。请告诉我 【参考方案1】:这是我的例子Fragment
:
public class MyDefaultFragment extends Fragment
//Default items
public static ArrayList<MyItem> myItems = new ArrayList<>();
//Search filter
public static String filter = "";
public MyDefaultFragment()
//require a empty constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
View view = inflater.inflate(R.layout.defaultfragment,container,false);
//I used a EditText instead of a SearchView
EditText editText = view.findViewById(R.id.filterEditText);
RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
recyclerView.setHasFixedSize(true);
//Checks for text change
Handler handler = new Handler();
handler.postDelayed(new Runnable()
@Override
public void run()
filter = editText.getText().toString();
handler.postDelayed(this,500);
,500);
//Updates the Database every second | 1000 millisecond = 1 second
Handler update = new Handler();
update.postDelayed(new Runnable()
@Override
public void run()
new MyDatabase.AsyncTask(MyDatabase.getInstance(getContext())).execute();
update.postDelayed(this,1000);
,1000);
//Creates a new object in the Adapter.class
Adapter adapter = new Adapter();
myItems.clear();
//example items
myItems.add(new MyItem(R.drawable.bcn100, "firstActivity"));
myItems.add(new MyItem(R.drawable.ada100, "secondActivity"));
myItems.add(new MyItem(R.drawable.cos100, "otherActivity"));
recyclerView.setAdapter(adapter);
//Updates the Database on open the Fragment
new MyDatabase.AsyncTask(MyDatabase.getInstance(getContext())).execute();
//observe the LiveData<List<MyItem>> to an List<MyItem>
MyItemViewModel myItemViewModel = new ViewModelProvider(this).get(MyItemViewModel.class);
myItemViewModel.getAllItems().observe(getViewLifecycleOwner(), adapter::setItems);
return view;
这是Adapter
的CardView
:
public class Adapter extends RecyclerView.Adapter<Adapter.CardHolder>
//Item list of the Adapter
public static List<MyItem> items = new ArrayList<>();
@NonNull
@Override
public CardHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
//CardView the name of the layout file smallcard
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.smallcard, parent, false);
CardHolder smallCardHolder = new CardHolder(itemView);
return smallCardHolder;
@Override
public void onBindViewHolder(@NonNull final CardHolder holder, int position)
//get the item of the position
MyItem myItem = items.get(position);
int image = myItem.getMyImage();
String name = myItem.getMyName();
holder.imageView.setImageResource(image);
holder.textViewName.setText(name);
//onClickListener for the cardView
if(holder.cardView!= null)
holder.cardView.setOnClickListener(v ->
openActivity(holder.textViewName.getText().toString());
);
//You have to put here the method to open the activitys
public void openActivity(String name)
switch (name)
case "firstActivity":
System.out.println("Open firstActivity");
break;
case "secondActivity":
System.out.println("Open secondActivity");
break;
case "otherActivity":
System.out.println("Open otherActivity");
break;
default:
break;
//Amount of items
@Override
public int getItemCount ()
return items.size();
public void setItems(List <MyItem> items)
this.items = items;
notifyDataSetChanged();
//Card Holder
class CardHolder extends RecyclerView.ViewHolder
private CardView cardView;
private ImageView imageView;
private TextView textViewName;
public CardHolder(@NonNull View itemView)
super(itemView);
cardView = itemView.findViewById(R.id.card_View);
imageView = itemView.findViewById(R.id.card_Image);
textViewName = itemView.findViewById(R.id.card_Name);
这是插入/删除CardView
的Database
//If you change the database schema you have to update the current version +1
@Database(entities = MyItem.class,version = 1)
public abstract class MyDatabase extends RoomDatabase
private static MyDatabase instance;
public abstract MyItemDao myItemDao();
public static synchronized MyDatabase getInstance(Context context)
//if the instance is null
if(instance == null)
instance = Room.databaseBuilder(context,MyDatabase.class,"my_Database")
.fallbackToDestructiveMigration()
.addCallback(callback)
.setAutoCloseTimeout(1, TimeUnit.SECONDS)
.build();
return instance;
private static Callback callback = new Callback()
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db)
super.onCreate(db);
new AsyncTask(instance).execute();
;
// The Async Task is deprecated you can use the Kotlin CoroutineAsyncTask instead of android.os.AsyncTask
// If you want to change it, this will help you
// https://***.com/questions/68136577/how-to-replace-asynctask-in-this-android-code/68137304#68137304
public static class AsyncTask extends android.os.AsyncTask<Void,Void,Void>
MyItemDao myItemDao;
public AsyncTask(MyDatabase myDatabase)
this.myItemDao = myDatabase.myItemDao();
@Override
protected Void doInBackground(Void... voids)
//default Items
List<MyItem> allDefaultItems = MyDefaultFragment.myItems;
//Current listed items in the RecyclerView
List<MyItem> allAdapterItems = Adapter.items;
String filter = MyDefaultFragment.filter;
int length = filter.length();
//Search method
if(length >0)
List<MyItem> deleteItems = new ArrayList<>();
List<MyItem> updateItems = new ArrayList<>();
allDefaultItems.forEach(myItem ->
if(myItem.myName.toLowerCase().startsWith(filter))
updateItems.add(myItem);
else
deleteItems.add(myItem);
);
myItemDao.delete(deleteItems);
myItemDao.insertAll(updateItems);
else
myItemDao.insertAll(allDefaultItems);
return null;
我的物品:
//If you want can change the tableName you have also change the name in the MyItemDao interface
@Entity(tableName = "myTable")
public class MyItem
int myImage;
//A PrimaryKey is require for a Database
@PrimaryKey
@NonNull
String myName;
public MyItem(int myImage,String myName)
this.myImage = myImage;
this.myName = myName;
public int getMyImage()
return myImage;
public void setMyImage(int myImage)
this.myImage = myImage;
public String getMyName()
return myName;
public void setMyName(String myName)
this.myName = myName;
MyItemDao.java
:
@Dao
public interface MyItemDao
//Select all data from myTable
@Query("Select * From myTable")
LiveData<List<MyItem>> getAllItems();
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List<MyItem> myItems);
@Delete
void delete(List<MyItem> myItems);
@Query("Delete from myTable")
void deleteAllItems();
存储库:
public class MyItemRepository
private LiveData<List<MyItem>> allItems;
private MyItemDao myItemDao;
public MyItemRepository(Application application)
MyDatabase myDatabase = MyDatabase.getInstance(application);
myItemDao = myDatabase.myItemDao();
allItems = myItemDao.getAllItems();
public void insertAll(List<MyItem> yItems) new InsertAllItemsAsyncTask(myItemDao).execute(myItems);
public void deleteItems(List<MyItem> myItems)
new DeleteItemListAsyncTask(myItemDao).execute(myItems);
public void deleteAllItems()
new DeleteAllItemsAsyncTask(myItemDao).execute();
public LiveData<List<MyItem>> getAllItems()
return allItems;
//Async tasks to put the items to the Database
private static class InsertAllItemsAsyncTask extends AsyncTask<List<MyItem>,Void,Void>
MyItemDao myItemDao;
private InsertAllItemsAsyncTask(MyItemDao myItemDao)
this.myItemDao = myItemDao;
@Override
protected Void doInBackground(List<MyItem>... lists)
myItemDao.insertAll(lists[0]);
return null;
private static class DeleteAllItemsAsyncTask extends AsyncTask<Void,Void,Void>
MyItemDao myItemDao;
private DeleteAllItemsAsyncTask(MyItemDao myItemDao)
this.myItemDao = myItemDao;
@Override
protected Void doInBackground(Void... voids)
myItemDao.deleteAllItems();
return null;
private static class DeleteItemListAsyncTask extends AsyncTask<List<MyItem>,Void,Void>
MyItemDao myItemDao;
private DeleteItemListAsyncTask(MyItemDao myItemDao)
this.myItemDao = myItemDao;
@Override
protected Void doInBackground(List<MyItem>... myItems)
myItemDao.delete(myItems[0]);
return null;
ViewModel
:
public class MyItemViewModel extends AndroidViewModel
//LiveData is require for the RoomDatabase
private LiveData<List<MyItem>> allItems;
private MyItemRepository myItemRepository;
public MyItemViewModel(Application application)
super(application);
this.myItemRepository = new MyItemRepository(application);
allItems = myItemRepository.getAllItems();
public LiveData<List<MyItem>> getAllItems()
return allItems;
public void insertAll(List<MyItem> myItems)
myItemRepository.insertAll(myItems);
//deletes a List of items
public void delete(List<MyItem> myItems)
myItemRepository.deleteItems(myItems);
public void deleteAllItems()
myItemRepository.deleteAllItems();
CardView
我叫它smallcard.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:orientation="horizontal"
android:layout_>
<androidx.cardview.widget.CardView
android:layout_
android:layout_
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="5dp"
android:backgroundTint="#ffffff"
android:id="@+id/card_View">
<RelativeLayout
android:layout_
android:layout_>
<ImageView
android:id="@+id/card_Image"
android:layout_
android:layout_
android:layout_marginStart="10dp"
android:scaleType="fitCenter"/>
<TextView
android:id="@+id/card_Name"
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Name"
android:textColor="?attr/colorPrimary"
android:textSize="18sp"
android:textStyle="bold"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
测试Fragment.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".MyDefaultFragment"
android:background="#ffffff">
<EditText
android:id="@+id/filterEditText"
android:layout_marginTop="10dp"
android:layout_
android:layout_
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_
android:layout_
android:clipToPadding="false"
android:layout_below="@id/filterEditText"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
/>
</RelativeLayout>
一些build.gradle(Module)
implementations
:
dependencies
implementation 'androidx.room:room-runtime:2.3.0'
annotationProcessor 'androidx.room:room-compiler:2.3.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.3.1'
implementation 'androidx.lifecycle:lifecycle-livedata:2.3.1'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.3.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
...
您将在代码中以 cmets 的形式找到更多信息。
更新
此外,我在github 上为您提供整个项目。单击卡片后,我添加了不同的意图。即使您正在搜索并且位置发生变化,它也会为同一张卡片打开相同的Fragment
。
【讨论】:
对不起,先生回复晚了,我正在努力找出答案。您能否详细说明如何使用此方法?由于我是初学者,我很抱歉这些问题。但真的很想了解它。 好的,不用担心。让我命名您需要创建和复制其中代码的类和 xml 文件。我建议打开一个新的空项目。使用上面的代码,您可以重现整个项目。然后尝试用 cmets 来理解它。这将是初学者的最佳方式。我在重命名所有内容时告诉你。 很抱歉给您带来不便。非常感谢,非常感谢! 我正在通过按卡片添加新意图。您将获得一个完整的功能项目来学习。我会发给你一个下载链接。再给我一点时间。 当然!谢谢楼主!以上是关于获取列表视图的arraylist的原始位置的主要内容,如果未能解决你的问题,请参考以下文章