2014-12-26 3 views
0

java.lang.IllegalStateException: Содержимое adapter изменилось, но ListView не получил уведомление. Убедитесь, что содержимое адаптера не изменено из фонового потока, но только из потока пользовательского интерфейса. Убедитесь, что ваш адаптер звонит notifyDataSetChanged()Listiview error после обновления получить новые данные

поэтому я работаю с пользовательским списком ListView, когда вы достигаете финала списка. Я показываю нижний колонтитул и создаю слушателя для реализации Activity/Fragment, который будет использовать listView , Моя проблема в том, что когда я вызываю службы этого метода и обновляю массив данными адаптера, я получил эту ошибку. Я называю слишком услуги на адаптере, потому что мне нужны данные конкретной строки.

Вот отхожу код:

Пользовательские ListView:

public class EndlessListView extends ListView implements OnScrollListener { 

    private View footer; 
    private boolean isLoading; 
    private EndlessListener listener; 
    private ArrayAdapter<?> adapter; 
    private boolean isReachEnd; 

    public EndlessListView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     this.setOnScrollListener(this); 
    } 

    public EndlessListView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.setOnScrollListener(this); 
    } 

    public EndlessListView(Context context) { 
     super(context); 
     this.setOnScrollListener(this); 
    } 

    public void refreshList() { 
     this.removeFooterView(footer); 
     this.requestLayout(); 
     adapter.notifyDataSetChanged(); 
     isLoading = false; 
    } 

    public void setListener(EndlessListener listener) { 
     this.listener = listener; 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
         int visibleItemCount, int totalItemCount) { 

     if (getAdapter() == null) 
      return; 

     if (getAdapter().getCount() == 0) 
      return; 

     int l = visibleItemCount + firstVisibleItem; 
     if (l >= totalItemCount && !isLoading && !isReachEnd) { 
      // It is time to add new data. We call the listener 
      this.addFooterView(footer); 
      this.requestLayout(); 
      isLoading = true; 
      listener.loadData(); 
     } 
    } 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
    } 

    public void setLoadingView(int resId) { 
     LayoutInflater inflater = (LayoutInflater) super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     footer = (View) inflater.inflate(resId, null); 
     this.addFooterView(footer); 

    } 

    public void setAdapter(ArrayAdapter<?> adapter) { 
     super.setAdapter(adapter); 
     this.adapter = adapter; 
     this.removeFooterView(footer); 
    } 

    public void addNewData(ArrayList data) { 
     this.removeFooterView(footer); 
     this.requestLayout(); 
     adapter.addAll(data); 
     adapter.notifyDataSetChanged(); 
     isLoading = false; 
    } 

    public void removeFooter() { 
     if (adapter != null) { 
      this.removeFooterView(footer); 
      isLoading = false; 
      this.adapter.notifyDataSetChanged(); 
      this.requestLayout(); 
     } 
    } 

    public void addFooter() { 
     if (adapter != null) { 
      this.addFooterView(footer); 
      isLoading = true; 
      this.adapter.notifyDataSetChanged(); 
      this.requestLayout(); 
     } 
    } 


    public EndlessListener setListener() { 
     return listener; 
    } 

    public static interface EndlessListener { 
     public void loadData(); 
    } 

    public boolean isReachEnd() { 
     return isReachEnd; 
    } 

    public void setReachEnd(boolean isReachEnd) { 
     this.isReachEnd = isReachEnd; 
    } 

    public boolean isLoading() { 
     return isLoading; 
    } 

    public void setLoading(boolean isLoading) { 
     this.isLoading = isLoading; 
    } 

    @Override 
    public ArrayAdapter<?> getAdapter() { 
     return adapter; 
    } 

    public View getFooter() { 
     return footer; 
    } 

    @Override 
    public void setClickable(boolean clickable) { 
     super.setClickable(clickable); 
    }} 

Получить данные и обновить массив адаптера:

public void getMatcher() { 
    try { 
     gettingMatcher = true; 
     Timber.i(getString(R.string.getting_mather)); 
     HomeRequest.createMatcherRequest(getActivity(), new RequestController.ResponseListener<JSONObject>() { 
      @Override 
      public void onStart() { 
       ((AuthorizedActivity) getActivity()).showProgress(true); 
      } 

      @Override 
      public void onResponse(JSONObject response) { 
       parseMatcher(response); 
      } 

      @Override 
      public void onError(int error, String message) { 
       gettingMatcher = false; 
       ((AuthorizedActivity) getActivity()).showProgress(false); 
       Utils.showToast(getActivity(), getString(R.string.error_unexpected)); 
      } 
     }); 
    } catch (Exception e) { 
     gettingMatcher = false; 
     Timber.e(e, getString(R.string.error_getting_matcher)); 
     Crashlytics.logException(e); 
    } 
} 

/** 
* Parse the data from the web services and load the UI 
* 
* @param response 
*/ 
private void parseMatcher(JSONObject response) { 
    MatcherResponse matcherResponse = new MatcherResponse(false, ""); 
    ArrayList<User> auxDiscover = new ArrayList<>(); 
    if (response == null) { 
     Timber.e(getString(R.string.error_empty_response)); 
     Utils.showToast(getActivity(), getString(R.string.error_empty_response)); 
     ((AuthorizedActivity) getActivity()).showProgress(false); 
     gettingMatcher = false; 
     return; 
    } 

    try { 
     Gson gson = new GsonBuilder() 
       .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 
       .create(); 
     matcherResponse = gson.fromJson(response.toString(), MatcherResponse.class); 
     if (matcherResponse.isSuccess()) { 
      auxDiscover = matcherResponse.getDiscover(); 
      if (auxDiscover.size() > 0) { 
       discoversData.addAll(auxDiscover); 
       adapter.notifyDataSetChanged(); 
       discovers.removeFooter(); 
      } 
     } else { 
      Timber.e(getString(R.string.error_parsing_matcher)); 
      Utils.showToast(getActivity(), getString(R.string.error_unexpected)); 
     } 
     gettingMatcher = false; 
     ((AuthorizedActivity) getActivity()).showProgress(false); 
    } catch (Exception e) { 
     ((AuthorizedActivity) getActivity()).showProgress(false); 
     gettingMatcher = false; 
     Timber.e(getString(R.string.error_parsing_matcher)); 
     Crashlytics.logException(e); 
    } 
} 

адаптер:

public class DiscoverEndlessAdapter extends ArrayAdapter { 

    private ArrayList<User> itemList; 
    private Context ctx; 
    private static OnClickDiscoverEvents onClickDiscoverEvents; 
    private DiscoverFragment fragment; 

    public DiscoverEndlessAdapter(Context ctx, ArrayList<User> itemList, OnClickDiscoverEvents onClickDiscoverEvents, DiscoverFragment fragment) { 
     super(ctx, R.layout.adapter_discover, itemList); 
     this.itemList = itemList; 
     this.ctx = ctx; 
     this.onClickDiscoverEvents = onClickDiscoverEvents; 
     this.fragment = fragment; 
    } 

    @Override 
    public int getCount() { 
     return itemList.size(); 
    } 

    @Override 
    public User getItem(int i) { 
     return itemList.get(i); 
    } 

    @Override 
    public long getItemId(int i) { 
     return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder = null; 
     return getDiscoverRow(position, convertView, parent, holder); 
    } 

    static class ViewHolder { 
     @InjectView(R.id.adapter_discover_title) 
     TextView title; 
     @InjectView(R.id.adapter_discover_subtitle) 
     TextView subTitle; 
     @InjectView(R.id.adapter_discover_avatar) 
     ImageView avatar; 
     @InjectView(R.id.adapter_discover_connect) 
     TextView connectWith; 
     @InjectView(R.id.adapter_discover_message) 
     ImageButton message; 
     @InjectView(R.id.adapter_discover_description) 
     TextView description; 
     @InjectView(R.id.adapter_discover_more) 
     ImageButton more; 
     @InjectView(R.id.adapter_discover_avatar_connection) 
     ImageView avatarConnection; 
     @InjectView(R.id.adapter_discover_avatar_connection_2) 
     ImageView avatarConnection2; 
     @InjectView(R.id.adapter_discover_avatar_connection_3) 
     ImageView avatarConnection3; 
     @InjectView(R.id.adapter_discover_avatar_connection_4) 
     ImageView avatarConnection4; 
     @InjectView(R.id.adapter_discover_connection_opacity) 
     TextView avatarConnectionOpacity; 
     @InjectView(R.id.adapter_discover_message) 
     ImageButton messageButton; 
     @InjectView(R.id.adapter_discover_more) 
     ImageButton optionButton; 

     /*OnClick*/ 
     @OnClick(R.id.adapter_discover_message) 
     public void onGoChat(View view) { 
      onClickDiscoverEvents.showProfile(view); 
     } 

     @OnClick(R.id.adapter_discover_more) 
     public void onShowMoreOption(View view) { 
      onClickDiscoverEvents.showOption(view); 
     } 

     private Context ctx; 

     public ViewHolder(View view, Context ctx) { 
      ButterKnife.inject(this, view); 
      this.ctx = ctx; 
     } 
    } 

    /** 
    * Create the view for the chat data row 
    * 
    * @param position 
    * @param convertView 
    * @param parent 
    * @param holder 
    * @return 
    */ 
    private View getDiscoverRow(int position, View convertView, ViewGroup parent, ViewHolder holder) { 
     try { 
      User user = getItem(position); 
      if (convertView != null) { 
       holder = (ViewHolder) convertView.getTag(); 
      } else { 
       LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       convertView = inflater.inflate(R.layout.adapter_discover, parent, false); 
       holder = new ViewHolder(convertView, ctx); 
       convertView.setTag(holder); 
      } 

      // Title 
      String title = Utils.getNameFromUser(user); 
      holder.title.setText(title); 

      // Subtitle 
      String subTitle = Utils.getRoleAndLocationFromUser(user); 
      holder.subTitle.setText(subTitle); 

      // Description 
      String description = user.getAccomplishment(); 
      holder.description.setText(description); 

      //Avatar 
      Utils.setImageToImageViewFromUrl(ctx, holder.avatar, user.getImage(), user.getFirstName(), user.getLastName()); 

      //ImageButtons 
      holder.more.setFocusable(false); 
      holder.message.setFocusable(false); 

      //CommonConnections 
      if (user.getCommonConnections() == null) 
       getCommonConnections(user.getId(), position); 
      else { 
       ArrayList<Connection> connections = user.getCommonConnections(); 
       if (connections.size() > 0) { 
        if ((connections.size() > 0) && (holder.avatarConnection.getVisibility() != View.VISIBLE)) { 
         Connection connection = connections.get(0); 
         Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection, connection.getImage(), connection.getFirstName(), connection.getLastName()); 
         holder.avatarConnection.setVisibility(View.VISIBLE); 
        } 

        if ((connections.size() > 1) && (holder.avatarConnection2.getVisibility() != View.VISIBLE)) { 
         Connection connection = connections.get(1); 
         Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection2, connection.getImage(), connection.getFirstName(), connection.getLastName()); 
         holder.avatarConnection2.setVisibility(View.VISIBLE); 
        } 

        if ((connections.size() > 2) && (holder.avatarConnection3.getVisibility() != View.VISIBLE)) { 
         Connection connection = connections.get(2); 
         Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection3, connection.getImage(), connection.getFirstName(), connection.getLastName()); 
         holder.avatarConnection3.setVisibility(View.VISIBLE); 
        } 

        if ((connections.size() > 3) && (holder.avatarConnection4.getVisibility() != View.VISIBLE)) { 
         Connection connection = connections.get(3); 
         Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection4, connection.getImage(), connection.getFirstName(), connection.getLastName()); 
         holder.avatarConnection4.setVisibility(View.VISIBLE); 
        } 

        if ((connections.size() > 4) && (holder.avatarConnectionOpacity.getVisibility() != View.VISIBLE)) { 
         int quantity = connections.size() - 4; 
         String moreConnections = "+" + quantity; 
         if (quantity > 0) { 
          holder.avatarConnectionOpacity.setText(moreConnections); 
          holder.avatarConnectionOpacity.setVisibility(View.VISIBLE); 
         } 
        } 
       } else { 
        if (isCommon(user.getSkills())) { 
         holder.avatarConnection.setImageResource(R.drawable.ic_common_skill); 
        } else 
         holder.avatarConnection.setVisibility(View.GONE); 

        if (isCommon(user.getCompanies())) { 
         holder.avatarConnection2.setImageResource(R.drawable.ic_common_work); 
        } else 
         holder.avatarConnection2.setVisibility(View.GONE); 

        holder.avatarConnection3.setVisibility(View.GONE); 
        holder.avatarConnection4.setVisibility(View.GONE); 
        holder.avatarConnectionOpacity.setVisibility(View.GONE); 
       } 
      } 

      //Buttons 
      holder.messageButton.setTag(user); 
      holder.optionButton.setTag(user); 

     } catch (Exception e) { 
      Timber.e(e, ctx.getString(R.string.error_getview_discover_adapter)); 
      Crashlytics.log(ctx.getString(R.string.error_getview_discover_adapter)); 
     } 

     return convertView; 
    } 


    public void getCommonConnections(long caliberId, final int position) { 
     try { 
      Timber.i(ctx.getString(R.string.getting_common_connections)); 
      HomeRequest.createCommonConnectionsRequest(ctx, caliberId, new RequestController. 
        ResponseListener<JSONObject>() { 
       @Override 
       public void onStart() { 

       } 

       @Override 
       public void onResponse(JSONObject response) { 
        parseCommonConnections(response, position); 
       } 

       @Override 
       public void onError(int error, String message) { 
        Toast.makeText(ctx, ctx.getString(R.string.error_unexpected), Toast.LENGTH_SHORT).show(); 
       } 
      }); 
     } catch (Exception e) { 
      Timber.e(e, ctx.getString(R.string.error_getting_common_connections)); 
      Crashlytics.logException(e); 
     } 
    } 

    /** 
    * Parse the data from the web services and load the UI 
    * 
    * @param response 
    */ 
    private void parseCommonConnections(JSONObject response, int position) { 
     CommonConnectionsResponse commonConnectionsResponse = new CommonConnectionsResponse(); 
     ArrayList<Connection> connections = new ArrayList<>(); 
     if (response == null) { 
      Timber.e(ctx.getString(R.string.error_empty_response)); 
      return; 
     } 

     try { 
      Gson gson = new GsonBuilder() 
        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 
        .create(); 
      commonConnectionsResponse = gson.fromJson(response.toString(), CommonConnectionsResponse.class); 
      if (commonConnectionsResponse.isSuccess()) { 
       itemList.get(position).setCommonConnections(commonConnectionsResponse.getConnections().getConnections()); 
       fragment.discoversData.get(position).setCommonConnections(commonConnectionsResponse.getConnections().getConnections()); 
      } else { 
       itemList.get(position).setCommonConnections(new ArrayList<Connection>()); 
       fragment.discoversData.get(position).setCommonConnections(new ArrayList<Connection>()); 
       Timber.i(ctx.getString(R.string.no_common_connections, Utils.getNameFromUser(fragment.discoversData.get(position)))); 
      } 
      notifyDataSetChanged(); 
     } catch (Exception e) { 
      Timber.e(ctx.getString(R.string.error_parsing_common_connections)); 
      Crashlytics.logException(e); 
     } 
    } 

    /** 
    * Return common value of skill or company object from list 
    * 
    * @param list 
    * @return 
    */ 
    private boolean isCommon(ArrayList<?> list) { 
     if ((list != null) && (list.size() > 0)) { 
      for (int i = 0; i < list.size(); i++) { 
       Object object = list.get(i); 
       if (object instanceof Skill) { 
        if (((Skill) object).isCommon()) 
         return true; 
       } else if (object instanceof Company) { 
        if (((Company) object).isCommon()) 
         return true; 
       } else 
        return false; 
      } 
     } else 
      return false; 
     return false; 
    } 
} 

Любой помощь будет значительно повышена лем, связанных.

ответ

0

Вы можете попытаться вызвать setAdapter (null), прежде чем изменять данные внутри адаптера.

Смежные вопросы