我在很多设备上测试我的应用程序并且工作正常......直到我在运行Android 7.1的Android设备上测试了回收器视图已经消失,而它存在于其他设备上我的代码:
RecyclerGridLayoutAdapter:
public class RecyclerGridLayoutAdapter extends RecyclerView.Adapter<RecyclerGridLayoutAdapter.ViewHolder>{
private int resource;
private ArrayList<Item> contacts;
private TreeMap<String,ArrayList<Contact>> gridsMap;
private String searchedString;
private Context activity;
private String myNumber;
public RecyclerGridLayoutAdapter(int resource, ArrayList<Item> contacts,Context activity) {
this.resource = resource;
this.contacts = contacts;
this.activity=activity;
gridsMap= DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabets();
loadData();
searchedString="";
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
v= LayoutInflater.from(activity).inflate(resource,parent,false);
ViewHolder vh=new ViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
Log.wtf("begin ","inserting "+contacts.get(position).type);
if(contacts.get(position).type==0){
holder.header.setVisibility(View.VISIBLE);
holder.header.setText(contacts.get(position).alphabet);
holder.name.setVisibility(View.GONE);
holder.image.setVisibility(View.GONE);
}
else {
holder.header.setVisibility(View.GONE);
holder.name.setVisibility(View.VISIBLE);
holder.image.setVisibility(View.VISIBLE);
SharedPreferences prefs=activity.getSharedPreferences("myNumber",0);
final String myNumber=prefs.getString("number","not pund");
holder.name.setText(contacts.get(position).contact.name);
if(contacts.get(position).contact.isRegistered.equalsIgnoreCase("true")){
holder.image.setBackgroundResource(R.drawable.contact_offline_pic);
holder.image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(activity, ChatRoomActivity.class);
AppMasterManager.activity=ChatRoomActivity.class;
intent.putExtra("room",contacts.get(position).contact.room);
intent.putExtra("contact_name",contacts.get(position).contact.name);
intent.putExtra("myNumber",myNumber);
if (contacts.get(position).contact.isPrivate.equalsIgnoreCase("true")){
if (!DatabaseHandler.getDataBaseHandler(activity).numberExist(contacts.get(position).contact.phone_number)){
DatabaseHandler.getDataBaseHandler(activity).addPrivateContact(contacts.get(position).contact);
try {
ChatService.bind.getService().joinANumber(contacts.get(position).contact);
} catch (JSONException e) {
e.printStackTrace();
}
}
intent.putExtra("account", Accounts.SECONDARY_ACCOUNT);
}else {
intent.putExtra("account", Accounts.PRIMARY_ACCOUNT);
}
Log.wtf("from grid adapter inflater",contacts.get(position).contact.room);
activity.startActivity(intent);
}
});
if(contacts.get(position).contact.state.equalsIgnoreCase("offline")){
holder.image.setBackgroundResource(R.drawable.contact_offline_pic);
}
else {
holder.image.setBackgroundResource(R.drawable.contact_online_pic);
}
}
else {
holder.image.setBackgroundResource(R.drawable.contact_unregistered_pic);
}
}
}
@Override
public int getItemCount() {
return contacts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView header;
public TextView name;
public ImageView image;
public ViewHolder(View itemView) {
super(itemView);
header=(TextView)itemView.findViewById(R.id.first_char_header);
name=(TextView)itemView.findViewById(R.id.contact_name);
image=(ImageView)itemView.findViewById(R.id.image_grid_contact);
}
}
@Override
public int getItemViewType(int position) {
if(contacts.get(position).type==0){
return 4;
}
else {
return 1;
}
}
public void search(String pattern){
searchedString=pattern;
if(!TextUtils.isEmpty(pattern)) {
searchedString=pattern;
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabetsWithPattern(pattern);
contacts.clear();
loadData();
}
else {
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabets();
contacts.clear();
loadData();
}
notifyDataSetChanged();
}
public void updateDataSet(){
if(!TextUtils.isEmpty(searchedString)){
contacts.clear();
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabetsWithPattern(searchedString);
loadData();
notifyDataSetChanged();
}
else {
contacts.clear();
gridsMap.clear();
gridsMap=DatabaseHandler.getDataBaseHandler(activity).getContactsByAlphabets();
loadData();
notifyDataSetChanged();
}
}
void loadData(){
for(String c:gridsMap.keySet()){
contacts.add(new Item(0,c));
Log.wtf("add","+");
for(Contact d:gridsMap.get(c)){
contacts.add(new Item(1,c,d));
}}
}
public void searchOnline(final String pattern) throws JSONException {
if(!TextUtils.isEmpty(pattern)){
JSONObject object=new JSONObject();
object.put("pattern",pattern);
JsonObjectRequest request_json = new JsonObjectRequest(WebServiceApi.SEARCH_SECONDARY_CONTACTS_ONLINE,object, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
if(response.getJSONArray("res").length()>0){
contacts.clear();
Log.w("result ",response.getJSONArray("res").getJSONObject(0).getJSONObject("secondary_account").getString("user_name").toString());
contacts.add(new Item(0,pattern.toCharArray()[0]+""));
for(int i=0;i<response.getJSONArray("res").length();i++){
String name=response.getJSONArray("res").getJSONObject(i).getJSONObject("secondary_account").getString("user_name");
String phone_number=response.getJSONArray("res").getJSONObject(i).getString("phone_number");
String room;
if(phone_number.compareTo(myNumber)>0){
room=phone_number+myNumber;
}
else {
room=myNumber+phone_number;
}
Contact contact=new Contact();
contact.name=name;
contact.room=room;
contact.phone_number=phone_number;
contact.isRegistered="true";
contact.state="offline";
contact.isPrivate="true";
contacts.add(new Item(1,pattern.toCharArray()[0]+"",contact));
}
notifyDataSetChanged();
}
else{
contacts.clear();
loadData();
notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("No Activity", error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(request_json);
}
else {
contacts.clear();
loadData();
notifyDataSetChanged();
}
}
public void setNumber(String number){
myNumber=number;
}
}
ContactsFragement:
public class ContactsFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnContactsFragementInteraction mListener;
private RecyclerView listContacts;
private GridLayoutManager manager;
private HashMap<String,Contact> roomMaps;
private String number;
private boolean isLoaded=false;
private RecyclerGridLayoutAdapter adapter;
public ContactsFragment() {
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment ContactsFragment.
*/
// TODO: Rename and change types and number of parameters
public static ContactsFragment newInstance(String param1, String param2) {
ContactsFragment fragment = new ContactsFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_contacts, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mListener.pressed();
if(savedInstanceState==null){Toast.makeText(getActivity(),"First Time running this fragment",Toast.LENGTH_SHORT).show();}
roomMaps = new HashMap<>();
listContacts = (RecyclerView) getActivity().findViewById(R.id.list_contacts);
EditText contact_search_box = (EditText) getActivity().findViewById(R.id.search_box_contacts);
contact_search_box.clearFocus();
number = this.getArguments().getString("number");
// contactsListAdapter = new ContactsListAdapterAlternative(getActivity(), new ArrayList<GridLayoutAdapter>(), R.layout.list_contacts_item);
// listContacts.setAdapter(contactsListAdapter);
manager=new GridLayoutManager(getActivity(),4);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (adapter.getItemViewType(position));
}
});
adapter=new RecyclerGridLayoutAdapter(R.layout.list_contacts_item,new ArrayList<Item>(),getActivity());
adapter.setNumber(number);
manager.setOrientation(LinearLayoutManager.VERTICAL);
listContacts.setLayoutManager(manager);
listContacts.setHasFixedSize(true);
listContacts.setAdapter(adapter);
EditText search_online_box=getActivity().findViewById(R.id.search_online);
search_online_box.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
adapter.searchOnline(s.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
contact_search_box.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
adapter.search(charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
isLoaded=true;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnContactsFragementInteraction) {
mListener = (OnContactsFragementInteraction) context;
mListener.pressed();
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
public void updateState(String room,HashMap<String,String> map) {
if(adapter!=null)
adapter.updateDataSet();
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnContactsFragementInteraction {
// TODO: Update argument type and name
void pressed();
ChatService getService();
void setRoutablity(boolean routablity);
}
}
fragment_contacts:
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/contactsFragment"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal"
android:id="@+id/topSearchBar"
android:weightSum="2">
<EditText
android:id="@+id/search_box_contacts"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="10dp"
android:textSize="15sp"
android:hint="search contacts"
android:background="#beddeb"/>
<EditText
android:id="@+id/search_online"
android:layout_width="0dp"
android:layout_height="match_parent"
android:hint="search online"
android:padding="10dp"
android:textSize="15sp"
android:background="#5fc0e9"
android:layout_weight="1"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/list_contacts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/topSearchBar"
android:scrollbars="vertical"
tools:listitem="@layout/list_contacts_item">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
list_contact_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/first_char_header"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="a"
android:paddingTop="6dp"
android:paddingLeft="8dp"
android:textSize="25sp"
android:textColor="#c1292f"
android:background="#f2f2f2"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:lines="2"
android:id="@+id/contact_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Abdallah"
android:padding="5dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:src="@drawable/contact_small"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:id="@+id/image_grid_contact"
android:background="@drawable/contact_offline_pic"/>
</LinearLayout>
</LinearLayout>
这个gridView只是一个联系人网格,它显示了我网络中可用和注册的所有联系人... 在日志中它显示它识别出已注册的联系人,甚至它收到一条消息,如果我打开聊天选项卡,我看到这个listview联系人发送消息,虽然回收者视图中没有出现联系...