使用新适配器更新recyclerview(Update recyclerview with new adapter)

编程入门 行业动态 更新时间:2024-10-12 14:20:52
使用新适配器更新recyclerview(Update recyclerview with new adapter)

我有一个片段,顶部有一个Searchview,在下面我显示了一个带有las 10个电话的通话记录。 要显示通话记录,我使用recyclerview和卡片。 这种行为很好,但现在我想实现其他的东西。

如果我在Searchview中搜索一个名字,我想做一些事情,比如结果列表更新时显示与联系人列表的巧合。 这是,我需要重复使用recyclerview,但此时,我将显示与联系人列表的巧合,而不是通话记录。

我使用过这里找到的代码但是没有用。 我正在做一些测试,看看有什么问题,我发现我无法重复使用recyclerview。

首先,我这样做是为了显示通话记录:

mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview); mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity())); mLogAdapter = new LogAdapter(DisplayCallLog()); mRecyclerView.setAdapter(mLogAdapter);

当searchview得到更新时,我正在尝试显示联系人列表以验证这是否有效:

public boolean onQueryTextChange(String query) { mContactAdapter = new ContactAdapter(ContactsList()); mRecyclerView.swapAdapter(mContactAdapter, true); //final List<ContactInfo> filteredModelList = filter(ContactsList(), query); //mContactAdapter.animateTo(filteredModelList); //mRecyclerView.scrollToPosition(0); return true; }

但我不能在同一个回收者视图上显示联系人列表。


编辑1 - >评论

我已经尝试在启动时加载联系人列表而不是日志列表,并且它也没有加载它。 也许问题是联系人列表要长吗?


编辑2 - >添加了广泛的代码

1)设置SearchView

我没有在操作栏中添加搜索视图,而是使用cardview来包含它。 这是phone_layout.xml 。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="60dp"> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" android:layout_gravity="center_horizontal" android:layout_marginLeft="80dp" android:layout_marginRight="80dp"> <android.support.v7.widget.SearchView android:id="@+id/dialpad_searchview" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:textSize="18sp" app:queryHint="@string/enter_phone_number" app:iconifiedByDefault="false" android:imeOptions="flagNoFullscreen"/> </android.support.v7.widget.CardView> </LinearLayout> <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_marginLeft="80dp" android:layout_marginRight="80dp"/>

2)设置适配器

首先,我定义了模型类ContactInfo 。 对于展位使用calllog和接触巧合,这是相同的。

public class ContactInfo { public int id; public String name; public String number; public String type; public int logType; public static final String ID_PREFIX = "ID_"; public static final String NUMBER_PREFIX = "Name_"; public static final String NAME_PREFIX = "Number_"; public static final String TYPE_PREFIX = "Type_"; public String getContactName() { return name; } public String getContactNumber() { return number; }

ContactViewHolder对于展位也是一样的。

public class ContactViewHolder extends RecyclerView.ViewHolder { protected TextView vName; protected TextView vType; protected ImageView vPic; public ContactViewHolder(View v) { super(v); vName = (TextView) v.findViewById(R.id.contactname); vType = (TextView) v.findViewById(R.id.contacttype); vPic = (ImageView) v.findViewById(R.id.contactpic); }

现在,每种用途的不同之处在于布局和适配器。 从calllog开始,这是phone_calllog_card.xml

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cardView" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" android:layout_marginBottom="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:selectableItemBackground"> <ImageView android:id="@+id/contactpic" android:tag="image_tag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="20dp"/> <TextView android:id="@+id/contactname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/contactpic" android:layout_marginLeft="40dp" android:text="Name" android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView android:id="@+id/contacttype" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/contactname" android:layout_toRightOf="@+id/contactpic" android:layout_marginLeft="40dp" android:text="Type" android:textAppearance="?android:attr/textAppearanceMedium"/> </RelativeLayout>

和LogAdapter类。

public class LogAdapter extends RecyclerView.Adapter<ContactViewHolder> { private List<ContactInfo> logList; public LogAdapter(List<ContactInfo> logList) { this.logList = logList; } @Override public int getItemCount() { return logList.size(); } @Override public void onBindViewHolder(ContactViewHolder contactViewHolder, int i) { final String number; String name; ContactInfo ci = logList.get(i); name = ci.name; if (name.equals("-2")) { name = "Private"; } contactViewHolder.vName.setText(name); contactViewHolder.vType.setText(ci.type); number = ci.number; } contactViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + number.trim())); if (ActivityCompat.checkSelfPermission(v.getContext(), Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) { v.getContext().startActivity(intent); } } }); } @Override public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View itemView = LayoutInflater. from(viewGroup.getContext()). inflate(R.layout.phone_calllog_card, viewGroup, false); return new ContactViewHolder(itemView); }

}

phone_contact_card.xml和ContactAdapter几乎与之前的版本不同,但几乎没有变化。

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cardView" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" android:layout_marginBottom="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:selectableItemBackground"> <ImageView android:id="@+id/contactpic" android:tag="image_tag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="20dp"/> <TextView android:id="@+id/contactname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/contactpic" android:layout_marginLeft="40dp" android:layout_centerVertical="true" android:text="Name" android:textAppearance="?android:attr/textAppearanceLarge"/> </RelativeLayout>

呼叫日志的适配器与联系重合之间的差异在于,当输入到片段时显示呼叫日志,并且它显示来自呼叫日志的10个静态结果。 但是由于接触巧合,每次你在serachview中输入一个字母来找到巧合时,它必须有某种动画来刷新列表,所以这里有一些附加的方法。

public class ContactAdapter extends RecyclerView.Adapter<ContactViewHolder> { private List<ContactInfo> contactList; public ContactAdapter(List<ContactInfo> contactList) { this.contactList = contactList; } @Override public int getItemCount() { return contactList.size(); } @Override public void onBindViewHolder(ContactViewHolder contactViewHolder, int i) { final String number; ContactInfo ci = contactList.get(i); contactViewHolder.vName.setText(ci.name); contactViewHolder.vPic.setImageResource(R.drawable.contact_icon_blue); number = ci.number; contactViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + number.trim())); if (ActivityCompat.checkSelfPermission(v.getContext(), Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) { v.getContext().startActivity(intent); } } }); } @Override public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View itemView = LayoutInflater. from(viewGroup.getContext()). inflate(R.layout.phone_contact_card, viewGroup, false); return new ContactViewHolder(itemView); } public void animateTo(List<ContactInfo> contacts) { applyAndAnimateRemovals(contacts); applyAndAnimateAdditions(contacts); applyAndAnimateMovedItems(contacts); } private void applyAndAnimateRemovals(List<ContactInfo> newContacts) { for (int i = contactList.size() - 1; i >= 0; i--) { final ContactInfo model = contactList.get(i); if (!newContacts.contains(model)) { removeItem(i); } } } private void applyAndAnimateAdditions(List<ContactInfo> newContacts) { for (int i = 0, count = contactList.size(); i < count; i++) { final ContactInfo model = newContacts.get(i); if (!contactList.contains(model)) { addItem(i, model); } } } private void applyAndAnimateMovedItems(List<ContactInfo> newContacts) { for (int toPosition = newContacts.size() - 1; toPosition >= 0; toPosition--) { final ContactInfo model = newContacts.get(toPosition); final int fromPosition = contactList.indexOf(model); if (fromPosition >= 0 && fromPosition != toPosition) { moveItem(fromPosition, toPosition); } } } public ContactInfo removeItem(int position) { final ContactInfo model = contactList.remove(position); notifyItemRemoved(position); return model; } public void addItem(int position, ContactInfo model) { contactList.add(position, model); notifyItemInserted(position); } public void moveItem(int fromPosition, int toPosition) { final ContactInfo model = contactList.remove(fromPosition); contactList.add(toPosition, model); notifyItemMoved(fromPosition, toPosition); }

3)实现逻辑

最后,在PhoneFragment ,这是实现所有这些工作的实现。

public class PhoneFragment extends Fragment implements SearchView.OnQueryTextListener { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.phone_layout, container, false); //query Searchview svContact.setOnQueryTextListener(this); //Recyclerview mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview); mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity())); //Loads the calllog mLogAdapter = new LogAdapter(DisplayCallLog()); mRecyclerView.setAdapter(mLogAdapter); //RecyclerView animation RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator(); itemAnimator.setAddDuration(1000); itemAnimator.setRemoveDuration(1000); mRecyclerView.setItemAnimator(itemAnimator); return view; }

注意:由于调用日志显示正确,我将避免在此处复制DisplayCallLog()方法太长。

当在searchview中输入文本时,我们定义新的适配器以实现在recyclerview中显示巧合的功能。

@Override public boolean onQueryTextChange(String query) { final List<ContactInfo> filteredModelList = filter(ContactsList(), query); mContactAdapter.animateTo(filteredModelList); mRecyclerView.scrollToPosition(0); return true; } private List<ContactInfo> filter(List<ContactInfo> contacts, String query) { query = query.toLowerCase(); final List<ContactInfo> filteredModelList = new ArrayList<>(); for (ContactInfo contact : contacts) { final String name = contact.getContactName().toLowerCase(); final String number = contact.getContactNumber().toLowerCase(); Log.i("FILTERED_QUERY", "name " + name + "/ number " + number); if (name.contains(query) || number.contains(query)) { filteredModelList.add(contact); } } return filteredModelList; } private ArrayList<ContactInfo> ContactsList() { ArrayList<ContactInfo> contactsList = new ArrayList<ContactInfo>(); int contactID = 0; String contactNumber = null; String contactName = null; ContactInfo cI; int resultLimit = 0; Cursor cursorContacts = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); while (cursorContacts.moveToNext() && resultLimit<10) { contactID = cursorContacts.getInt(cursorContacts.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.CONTACT_ID)); contactNumber = cursorContacts.getString(cursorContacts.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.NUMBER)); contactName = cursorContacts.getString(cursorContacts.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); cI = new ContactInfo(); cI.id = contactID; cI.name = contactName; cI.number = contactNumber; Log.i("CONTACT_INFO", cI.toString()); resultLimit++; } cursorContacts.close(); return contactsList; }

编辑3 - >新信息

我试着在启动时只显示联系人。 因此,我应该看到一个联系人列表,而不是可视化日志。 所以在片段的onCreateView中我只是这样做:

mContactAdapter = new ContactAdapter(ContactsList()); mRecyclerView.setAdapter(mContactAdapter);

而不是我以前做过的事情:

mLogAdapter = new LogAdapter(DisplayCallLog()); mRecyclerView.setAdapter(mLogAdapter);

这样,我只是使用一个适配器,如果这是问题,它应该工作。 但是没有用。 所以这个问题必须与我实现联系的方式有关(我说的是从联系人列表中获取联系人的原始列表,而不是过滤它们),或者是ContactAdapter中的错误。 但是这个适配器和LogAdapter几乎完全相同,所以我不知道......

I have a fragment whith a Searchview at the top, and below this I show a call log with the las 10 calls. To show the call log I use recyclerview with cards. This behaviour works fine, but now I want to implement something else.

If I search a name in the Searchview, I would like to do something like when a result list gets updated showing the coincidences with the contact list. This is, I would need to reuse the recyclerview, but at this time, instead of the call log, I will show coincidences with the contact list.

I've used code found here, but is not working. I'm making some test to see what is wrong and I've found that I'm not able to reuse the recyclerview.

At first, I do this to show the call log:

mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview); mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity())); mLogAdapter = new LogAdapter(DisplayCallLog()); mRecyclerView.setAdapter(mLogAdapter);

And when the searchview get's updated, I'm trying just showing the contactlist to verify that this is working:

public boolean onQueryTextChange(String query) { mContactAdapter = new ContactAdapter(ContactsList()); mRecyclerView.swapAdapter(mContactAdapter, true); //final List<ContactInfo> filteredModelList = filter(ContactsList(), query); //mContactAdapter.animateTo(filteredModelList); //mRecyclerView.scrollToPosition(0); return true; }

But I don't get to show the contactlist on the same recyclerview.


EDIT 1 -> Comment

I've tried loading the contactlist at startup instead of the loglist, and it does not load it neither. Maybe the problem is that the contactlist is to long?


EDIT 2 -> Extensive code added

1) Set up the SearchView

Instead of adding the searchview in the actionbar, I use a cardview to contain it. This is the phone_layout.xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="60dp"> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" android:layout_gravity="center_horizontal" android:layout_marginLeft="80dp" android:layout_marginRight="80dp"> <android.support.v7.widget.SearchView android:id="@+id/dialpad_searchview" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:textSize="18sp" app:queryHint="@string/enter_phone_number" app:iconifiedByDefault="false" android:imeOptions="flagNoFullscreen"/> </android.support.v7.widget.CardView> </LinearLayout> <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_marginLeft="80dp" android:layout_marginRight="80dp"/>

2) Set up the adapter

First I define the model class ContactInfo. This is same for booth uses calllog and contact coincidences.

public class ContactInfo { public int id; public String name; public String number; public String type; public int logType; public static final String ID_PREFIX = "ID_"; public static final String NUMBER_PREFIX = "Name_"; public static final String NAME_PREFIX = "Number_"; public static final String TYPE_PREFIX = "Type_"; public String getContactName() { return name; } public String getContactNumber() { return number; }

The ContactViewHolder is also the same for booth.

public class ContactViewHolder extends RecyclerView.ViewHolder { protected TextView vName; protected TextView vType; protected ImageView vPic; public ContactViewHolder(View v) { super(v); vName = (TextView) v.findViewById(R.id.contactname); vType = (TextView) v.findViewById(R.id.contacttype); vPic = (ImageView) v.findViewById(R.id.contactpic); }

Now, what is diferent for each use is the layout and the adapter. Starting from the calllog, here is the phone_calllog_card.xml

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cardView" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" android:layout_marginBottom="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:selectableItemBackground"> <ImageView android:id="@+id/contactpic" android:tag="image_tag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="20dp"/> <TextView android:id="@+id/contactname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/contactpic" android:layout_marginLeft="40dp" android:text="Name" android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView android:id="@+id/contacttype" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/contactname" android:layout_toRightOf="@+id/contactpic" android:layout_marginLeft="40dp" android:text="Type" android:textAppearance="?android:attr/textAppearanceMedium"/> </RelativeLayout>

And the LogAdapter class.

public class LogAdapter extends RecyclerView.Adapter<ContactViewHolder> { private List<ContactInfo> logList; public LogAdapter(List<ContactInfo> logList) { this.logList = logList; } @Override public int getItemCount() { return logList.size(); } @Override public void onBindViewHolder(ContactViewHolder contactViewHolder, int i) { final String number; String name; ContactInfo ci = logList.get(i); name = ci.name; if (name.equals("-2")) { name = "Private"; } contactViewHolder.vName.setText(name); contactViewHolder.vType.setText(ci.type); number = ci.number; } contactViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + number.trim())); if (ActivityCompat.checkSelfPermission(v.getContext(), Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) { v.getContext().startActivity(intent); } } }); } @Override public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View itemView = LayoutInflater. from(viewGroup.getContext()). inflate(R.layout.phone_calllog_card, viewGroup, false); return new ContactViewHolder(itemView); }

}

The phone_contact_card.xml and the ContactAdapter are almost indetical to these previous ones, but with few variations.

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cardView" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" android:layout_marginBottom="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:selectableItemBackground"> <ImageView android:id="@+id/contactpic" android:tag="image_tag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="20dp"/> <TextView android:id="@+id/contactname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/contactpic" android:layout_marginLeft="40dp" android:layout_centerVertical="true" android:text="Name" android:textAppearance="?android:attr/textAppearanceLarge"/> </RelativeLayout>

The diference between the Adapter for the call log and the contact coincidences is that the call log is shown when entered to the fragment and it shows 10 static results from the call log. But with the contact coincidences, it must have some kind of animation to refresh the list each time you enter a letter in the serachview to find coincidences, so here are some aditional methods.

public class ContactAdapter extends RecyclerView.Adapter<ContactViewHolder> { private List<ContactInfo> contactList; public ContactAdapter(List<ContactInfo> contactList) { this.contactList = contactList; } @Override public int getItemCount() { return contactList.size(); } @Override public void onBindViewHolder(ContactViewHolder contactViewHolder, int i) { final String number; ContactInfo ci = contactList.get(i); contactViewHolder.vName.setText(ci.name); contactViewHolder.vPic.setImageResource(R.drawable.contact_icon_blue); number = ci.number; contactViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + number.trim())); if (ActivityCompat.checkSelfPermission(v.getContext(), Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) { v.getContext().startActivity(intent); } } }); } @Override public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View itemView = LayoutInflater. from(viewGroup.getContext()). inflate(R.layout.phone_contact_card, viewGroup, false); return new ContactViewHolder(itemView); } public void animateTo(List<ContactInfo> contacts) { applyAndAnimateRemovals(contacts); applyAndAnimateAdditions(contacts); applyAndAnimateMovedItems(contacts); } private void applyAndAnimateRemovals(List<ContactInfo> newContacts) { for (int i = contactList.size() - 1; i >= 0; i--) { final ContactInfo model = contactList.get(i); if (!newContacts.contains(model)) { removeItem(i); } } } private void applyAndAnimateAdditions(List<ContactInfo> newContacts) { for (int i = 0, count = contactList.size(); i < count; i++) { final ContactInfo model = newContacts.get(i); if (!contactList.contains(model)) { addItem(i, model); } } } private void applyAndAnimateMovedItems(List<ContactInfo> newContacts) { for (int toPosition = newContacts.size() - 1; toPosition >= 0; toPosition--) { final ContactInfo model = newContacts.get(toPosition); final int fromPosition = contactList.indexOf(model); if (fromPosition >= 0 && fromPosition != toPosition) { moveItem(fromPosition, toPosition); } } } public ContactInfo removeItem(int position) { final ContactInfo model = contactList.remove(position); notifyItemRemoved(position); return model; } public void addItem(int position, ContactInfo model) { contactList.add(position, model); notifyItemInserted(position); } public void moveItem(int fromPosition, int toPosition) { final ContactInfo model = contactList.remove(fromPosition); contactList.add(toPosition, model); notifyItemMoved(fromPosition, toPosition); }

3) Implementing logic

Finally, in the PhoneFragment, this is the implementation to make all this work.

public class PhoneFragment extends Fragment implements SearchView.OnQueryTextListener { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.phone_layout, container, false); //query Searchview svContact.setOnQueryTextListener(this); //Recyclerview mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview); mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity())); //Loads the calllog mLogAdapter = new LogAdapter(DisplayCallLog()); mRecyclerView.setAdapter(mLogAdapter); //RecyclerView animation RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator(); itemAnimator.setAddDuration(1000); itemAnimator.setRemoveDuration(1000); mRecyclerView.setItemAnimator(itemAnimator); return view; }

Note: As the call log is showing correctly, I'll avoid copying here the DisplayCallLog() method as is too long.

When text is entered in the searchview, we define the new adapter to achieve the functionallity of showing coincidences in the recyclerview.

@Override public boolean onQueryTextChange(String query) { final List<ContactInfo> filteredModelList = filter(ContactsList(), query); mContactAdapter.animateTo(filteredModelList); mRecyclerView.scrollToPosition(0); return true; } private List<ContactInfo> filter(List<ContactInfo> contacts, String query) { query = query.toLowerCase(); final List<ContactInfo> filteredModelList = new ArrayList<>(); for (ContactInfo contact : contacts) { final String name = contact.getContactName().toLowerCase(); final String number = contact.getContactNumber().toLowerCase(); Log.i("FILTERED_QUERY", "name " + name + "/ number " + number); if (name.contains(query) || number.contains(query)) { filteredModelList.add(contact); } } return filteredModelList; } private ArrayList<ContactInfo> ContactsList() { ArrayList<ContactInfo> contactsList = new ArrayList<ContactInfo>(); int contactID = 0; String contactNumber = null; String contactName = null; ContactInfo cI; int resultLimit = 0; Cursor cursorContacts = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); while (cursorContacts.moveToNext() && resultLimit<10) { contactID = cursorContacts.getInt(cursorContacts.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.CONTACT_ID)); contactNumber = cursorContacts.getString(cursorContacts.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.NUMBER)); contactName = cursorContacts.getString(cursorContacts.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); cI = new ContactInfo(); cI.id = contactID; cI.name = contactName; cI.number = contactNumber; Log.i("CONTACT_INFO", cI.toString()); resultLimit++; } cursorContacts.close(); return contactsList; }

EDIT 3 -> New info

I've tryed showing just the contacts at startup. So, instead of visualizing the log, I should see a contacts list. So in fragment's onCreateView I just do this:

mContactAdapter = new ContactAdapter(ContactsList()); mRecyclerView.setAdapter(mContactAdapter);

Instead of what I was doing before:

mLogAdapter = new LogAdapter(DisplayCallLog()); mRecyclerView.setAdapter(mLogAdapter);

This way, I'm just using one adapter, and if this is the problem, it should work. But is not working. So the problem must be something related to the way I achieve the contacts (I'm talking about getting the raw list of contacts from the contact list, without filtering them), or something that is wrong in the ContactAdapter. But this adapter and the LogAdapter are almost identical, so i don't know...

最满意答案

我想我遇到了问题。 这是因为你使用了几个适配器,用于显示日志和呼叫数据的示例。 首先,您需要做什么,它只使用单个适配器和项目类型的不同视图。 RecyclerView具有针对不同ViewHolder的实现 - 请看这个例子 。

首先,尝试使用上面的示例,仅使用单个适配器和不同的项类型。 如果问题仍然存在,我将在稍后使用上面的资源提供示例。

UPDATE!

因此,我希望您能够正确理解,使用多个适配器可能会在下次更新视图时出现问题(事件这不是您问题的关键,因为RecyclerView会缓存ViewHolders)。 并且您的示例中不需要使用多个适应器。 另一件事,我不明白上面的所有代码作品。 有关更多信息,需要调试所有项目...

但我也更新了可搜索样本(上面链接)的工作,使用了几个Item ViewHolder类型的例子和不同的搜索,下面是结果。 无论如何,它比使用几个适配器更好的解决方案。 我也在Github Later中共享代码。

更新GITHUB链接!

在此处输入图像描述 在此处输入图像描述

I think I get the problem. And it's because you using several Adapters, for showing examples of Log and Call data. So first, what you need to do, it's use only single adapter and different view for item types. RecyclerView has implementation for different ViewHolder - look at this example.

First, try with example above, by using only single adapter and different item types. If problem is still active, I'll provide example later, using your resource above.

UPDATE!

So, I want you to understand correctly, that using several adapters may produce problems with updating views next time (event this is not a key of your question, cause RecyclerView caches ViewHolders). And there is no need to use several adaptes in your examples. Another things, that I don't understand all works of code above. For more information need to debug all your project...

But I also updated work of Searchable Samples (linked above) to use several examples of Item ViewHolder Types and different in searching, below is result. Anyway it's better solution, than using several Adapters. Also I share code in Github Later.

UPDATE GITHUB LINKS!

enter image description here enter image description here

更多推荐

本文发布于:2023-08-04 01:28:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1405441.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:适配器   recyclerview   adapter   Update

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!