java.lang.IllegalStateException:
adapter
的内容已更改,但ListView未收到通知。确保不从后台线程修改适配器的内容,而只是从UI线程修改。确保您的适配器调用notifyDataSetChanged()
所以当你到达列表的最后时我正在使用自定义listView我会显示一个页脚视图,并在将使用listView的Activity / Fragment上创建一个实现的监听器。我的问题是当我在这个方法上调用服务并使用适配器的数据更新数组时我收到了该错误。我在适配器上调用了一个服务,因为我需要特定显示行的数据。
这是我的代码:
自定义列表视图:
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 :(得分:0)
您可以在修改适配器内的数据之前尝试调用setAdapter(null)。