2017-01-16 10 views
2

У меня проблема с моим RecyclerView. Я хочу обновить Карты (внутри RecyclerView) после получения данных с сервера. Сначала я подумал, что есть проблема с извлечением или разбором данных JSON или отправкой данных через EventBus в Fragment, но когда я показываю проанализированные объекты в TextView во Фрагменте, все отображается. Таким образом, реальной проблемой является RecyclerView/Adapter. Я инициализировал RecyclerView с пустым ArrayList, но когда и как мне нужно обновлять данные для RecyclerView? I've также читал некоторые сообщения здесь на Stackoverflow, но я не нашел подходящего решения ...обновление RecyclerView после извлечения данных с сервера

Это onCreateView из UserFragment

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

    // Inflate the layout for this fragment 
    View mView = inflater.inflate(R.layout.fragment_users, container, false); 
    mRecyclerView = (RecyclerView) mView.findViewById(R.id.rv_user); 
    //set LayoutManager for View 
    mLayoutManager = new LinearLayoutManager(getActivity()); 
    mRecyclerView.setLayoutManager(mLayoutManager); 

    //set Adapter for View 
    mAdapter = new UserAdapter(userList); 
    mRecyclerView.setAdapter(mAdapter); 
    Log.d(TAG, "onCreateView"); 
    return mView; 
} 

и это мой UserAdapter

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> { 

public static final String TAG = "UserAdapter"; 

private ArrayList<User> mUser; 

public UserAdapter(ArrayList<User> user) { 
    mUser = user; 
} 

public static class ViewHolder extends RecyclerView.ViewHolder { 
    public CardView cv; 
    public TextView user_name; 
    public TextView user_lastName; 

    public TextView user_city; 
    public ViewHolder(View itemView) { 
     super(itemView); 
     cv = (CardView) itemView.findViewById(R.id.rv_user); 
     user_name = (TextView) itemView.findViewById(R.id.tv_user_name); 
     user_lastName = (TextView) itemView.findViewById(R.id.tv_user_lastname); 
     user_city = (TextView) itemView.findViewById(R.id.tv_user_city); 
     Log.d(TAG, "Viewholder"); 
    } 

} 

//initialize Viewholder 
@Override 
public UserAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 
    View mView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_layout_person, viewGroup, false); 
    Log.d(TAG, "onCreateViewHolder"); 
    return new ViewHolder(mView); 
} 

//Bind data to view 
@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    holder.user_name.setText(mUser.get(position).getUser().getFirstname()); 
    holder.user_lastName.setText(mUser.get(position).getUser().getLastname()); 
    holder.user_city.setText(mUser.get(position).getUser().getCity()); 
    Log.d(TAG, "onBindViewHolder"); 
} 

public void setUserList(ArrayList<User> user){ 
    this.mUser = user; 
    notifyItemRangeChanged(0, user.size()); 
    notifyDataSetChanged(); 
} 

public void updateData(ArrayList<User> userList) { 
    mUser.clear(); 
    mUser.addAll(userList); 
    notifyDataSetChanged(); 
} 

public void removeItem(int position) { 
    mUser.remove(position); 
    notifyItemRemoved(position); 
} 

@Override 
public int getItemCount() { 
    Log.d(TAG, "getItemCount"); 
    if (mUser == null) { 
     return 0; 
    } else { 
     return mUser.size(); 
    } 
} } 

Это onResponse в MainActivity:

public void onResponse(Call call, Response response) throws IOException { 
      if (response.isSuccessful()) { 
       String responseStr = response.body().string(); 
       Gson gson = new Gson(); 
       Type userListType = new TypeToken<ArrayList<User>>() { 
       }.getType(); 
       final ArrayList<User> userList = gson.fromJson(responseStr, userListType); 
       CustomMessageEvent event = new CustomMessageEvent(); 
       event.setUserList(userList); 
       EventBus.getDefault().post(event); 
       System.out.print(responseStr); 
       response.body().close(); 
      } 
     } 

UPDATE

XML-файла (CardView)

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
           xmlns:app="http://schemas.android.com/apk/res-auto" 
           xmlns:tools="http://schemas.android.com/tools" 
           android:id="@+id/rv_user" 
           android:layout_width="match_parent" 
           android:layout_height="120dp" 
           android:layout_margin="3dp" 
           android:elevation="11dp" 
           android:foregroundGravity="center_horizontal" 
           android:scrollbars="vertical" 
           android:theme="@style/AppThemeFSF" 
           app:cardBackgroundColor="@color/cardview_light_background" 
           app:cardCornerRadius="4dp" 
           app:cardElevation="4dp" 
> 

<LinearLayout 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <android.support.v7.widget.AppCompatImageView 
     android:id="@+id/iv_profile_picture" 
     android:layout_width="80dp" 
     android:layout_height="80dp" 
     android:layout_gravity="center_vertical" 
     android:layout_marginBottom="8dp" 
     android:layout_marginStart="8dp" 
     android:layout_marginTop="8dp" 
     android:layout_weight="1" 
     android:src="@mipmap/ic_launcher"/> 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:orientation="vertical"> 

     <TextView 
      android:id="@+id/textView2" 
      android:layout_width="wrap_content" 
      android:layout_height="30dp" 
      android:layout_marginBottom="8dp" 
      android:layout_marginEnd="8dp" 
      android:layout_marginStart="8dp" 
      android:layout_marginTop="8dp" 
      android:layout_weight="1" 
      android:gravity="left|center" 
      android:text="Name"/> 

     <TextView 
      android:id="@+id/textView3" 
      android:layout_width="wrap_content" 
      android:layout_height="30dp" 
      android:layout_marginBottom="8dp" 
      android:layout_marginEnd="8dp" 
      android:layout_marginStart="8dp" 
      android:layout_weight="1" 
      android:gravity="left|center" 
      android:text="Nachname"/> 

     <TextView 
      android:id="@+id/textView" 
      android:layout_width="wrap_content" 
      android:layout_height="30dp" 
      android:layout_marginBottom="8dp" 
      android:layout_marginEnd="8dp" 
      android:layout_marginStart="8dp" 
      android:layout_weight="1" 
      android:gravity="left|center" 
      android:text="Stadt"/> 
    </LinearLayout> 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:orientation="vertical"> 

     <TextView 
      android:id="@+id/tv_user_name" 
      android:layout_width="wrap_content" 
      android:layout_height="30dp" 
      android:layout_marginBottom="8dp" 
      android:layout_marginEnd="8dp" 
      android:layout_marginStart="8dp" 
      android:layout_marginTop="8dp" 
      android:layout_weight="1" 
      android:gravity="left|center" 
      android:text="Name" 
      android:textAppearance="?android:textAppearanceLarge" 
      android:textSize="14sp"/> 

     <TextView 
      android:id="@+id/tv_user_lastname" 
      android:layout_width="wrap_content" 
      android:layout_height="30dp" 
      android:layout_marginBottom="8dp" 
      android:layout_marginEnd="8dp" 
      android:layout_marginStart="8dp" 
      android:layout_weight="1" 
      android:gravity="left|center" 
      android:text="Nachname" 
      android:textAppearance="?android:textAppearanceLarge" 
      android:textSize="14sp"/> 

     <TextView 
      android:id="@+id/tv_user_city" 
      android:layout_width="wrap_content" 
      android:layout_height="30dp" 
      android:layout_marginBottom="8dp" 
      android:layout_marginEnd="8dp" 
      android:layout_marginStart="8dp" 
      android:layout_weight="1" 
      android:gravity="left|center" 
      android:text="Stadt" 
      android:textAppearance="?android:textAppearanceLarge" 
      android:textSize="14sp" 
      /> 

    </LinearLayout> 

</LinearLayout> 

Snippet from AS

Snippet from Logcat

Заранее спасибо, ребята, есть великий день!

+0

Когда вы закончите загрузку данных, обновить список внутри адаптера с новыми данными и вызвать notifyItemRangeInserted – cuoka

+0

I've обновленный список, но ничего не произошло .. :(Возможно ли, что есть общая проблема с RecyclerView, вызывают НИЧЕГО, показывается ... Я вижу пустой фрагмент. – Andy

+0

Опубликуйте код, в котором вы загружаете данные и обновляете адаптер, пожалуйста. Также опубликуйте, какой метод getItemCount() возвращает впоследствии – cuoka

ответ

0

Хорошо, ребята ... У меня есть решение!И это заставляет меня немного сумасшедшим ... Проблема заключалась не в Адаптере или в ViewHolder, ни в чем-либо внутри Фрагмента. «Реальная» проблема заключалась в размере текста из TextView внутри элементов CardView-Elements. Я удалил эти свойства, и теперь доступен каждый набор данных! Большое вам спасибо за помощь и советы! Ты замечательный!

HAPPY кодирования;)

-1

Попробуйте изменить

public void setUserList(ArrayList<User> user){ 
    this.mUser = user; 
    notifyItemRangeChanged(0, user.size()); 
    notifyDataSetChanged(); 
} 

к этому

public void setUserList(ArrayList<User> user){ 
     mUser.add(user); 
     notifyItemInserted(user.size()); 
     notifyDataSetChanged(); 
    } 

Тогда в вашем фрагменте, вызовите

mAdapter.setUserList (USERLIST);

+0

Ваш код не имеет смысла. 'notifyItemInserted', уведомляющий об этом 1 добавленном элементе. – Divers

+0

ОК ... этот выглядит хорошо! теперь карты отображаются .. но только карты - без свойств пользователей. :(Я думаю, что-то неправильно с моим наблюдателем. – Andy

+0

Не можете ли вы напрямую вызвать getProperties и просто удалить getUser()? ** holder.user_name.setText (mUser.get (position) .getFirstname()) ; ** –

1

Проблема в том, что вы не подписываетесь на получение события назад. Таким образом, когда вы позвоните:

EventBus.getDefault().post(event); 

Никто не может получить событие! И вы не заполняете список. Так что вашему адаптеру нечего показывать.

Подписаться на события, как это:

@Subscribe 
public void receiveEvent(CustomMessageEvent event){ 
    mAdapter.updateData(event.getUserList()) 
} 

Этот метод должен быть в ваших фрагментов. Если вы поместите это внутри своего адаптера, вы нарушите принцип единой ответственности. Единственная ответственность, которую должен иметь ваш адаптер, - это связать список с RecyclerView.

Счастливое кодирование!

+0

Спасибо за ваш ответ. Итак ... ваше предложение является «главным способом» работы с eventbus, и поэтому я сделал это в первый раз. Теперь я изменил все содержимое кода в своем решении, но ничего не изменилось :(Это сумасшествие ... Я все еще вижу только пустые карты внутри моего RecyclerView! Я зарегистрировал все методы, также onBindViewHolder и onEvent (в Фрагмент), и я получаю событие, и я могу регистрировать данные, но мой ViewHolder не устанавливает данные в полях. I'm freakin out :( – Andy

+0

Можете ли вы поделиться кодом XML recycler itens? проблема есть. –

+0

Я обновил свое исходное сообщение;) – Andy