我正在尝试检查Tweet
列表中的项目:
public class Tweet implements Parcelable {
private int color;
private String pseudo;
private String text;
public Tweet(int color, String pseudo, String text) {
this.color = color;
this.pseudo = pseudo;
this.text = text;
}
public int getColor(){ return this.color; }
public String getPseudo(){ return this.pseudo; }
public String getText(){ return this.text; }
public int setColor(){ return this.color; }
public String setPseudo(){ return this.pseudo; }
public String setText(){ return this.text; }
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(pseudo);
out.writeString(text);
out.writeInt(color);
}
public static final Parcelable.Creator<Tweet> CREATOR = new Parcelable.Creator<Tweet>() {
public Tweet createFromParcel(Parcel in) {
return new Tweet(in);
}
public Tweet[] newArray(int size) {
return new Tweet[size];
}
};
protected Tweet(Parcel in) {
pseudo = in.readString();
text = in.readString();
color = in.readInt();
}
}
这里是主要活动的代码:
public class MainActivity extends AppCompatActivity {
private ListView _m_list_view;
TweetAdapter _m_tweet_adaptateur;
List<Tweet> _m_tweets;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_m_list_view = (ListView) findViewById(R.id.list_view);
_m_tweets = genererTweets();
_m_tweet_adaptateur = new TweetAdapter(MainActivity.this,
_m_tweets, _m_list_view.getChoiceMode());
_m_list_view.setAdapter(_m_tweet_adaptateur);
_m_list_view.setClickable(true);
_m_list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent tmp_intent;
// lancement 2nde activité avec un seul item
tmp_intent = new Intent(MainActivity.this, ShowTweetDetailActivity.class);
//startActivityForResult(tmp_intent, 0);*
tmp_intent.putExtra("tweet",(Tweet)_m_list_view.getItemAtPosition(position));
startActivity(tmp_intent);
}
});
_m_list_view.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
_m_list_view.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
_m_tweet_adaptateur.setChoiseMode(_m_list_view.getChoiceMode());
_m_list_view.setItemChecked(i, true);
return true;
}
});
_m_list_view.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode actionMode, int i, long l, boolean b) {
updateActionModeTitle(actionMode);
}
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu_tweet, menu);
actionMode.setCustomView(LayoutInflater.from(MainActivity.this).inflate(R.layout.menu_select_tweet, null));
updateActionModeTitle(actionMode);
return(true);
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
//quand on appui sur ok dans le menu
case R.id.item_select_multi_tweet:
/* int ii;
int tmp_key;
Intent tmp_intent;
ArrayList tmp_list;
SparseBooleanArray tmp_checked_list;
tmp_list = new ArrayList();
tmp_checked_list = _m_list_view.getCheckedItemPositions();
if (tmp_checked_list != null) {
for (ii = 0; ii < tmp_checked_list.size(); ii++) {
tmp_key = tmp_checked_list.keyAt(ii);
if (tmp_checked_list.get(tmp_key)) {
tmp_list.add(_m_list_view.getItemAtPosition(tmp_key));
}
}
tmp_intent = new Intent(MainActivity.this, ShowTweetDetailActivity.class);
//startActivityForResult(tmp_intent, 0);*
tmp_intent.putExtra("tweet",tmp_list);
startActivity(tmp_intent);
}
return true;*/
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
_m_list_view.setChoiceMode(ListView.CHOICE_MODE_NONE);
_m_tweet_adaptateur.setChoiseMode(_m_list_view.getChoiceMode());
_m_list_view.setAdapter(_m_tweet_adaptateur);
}
});
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
getMenuInflater().inflate(R.menu.context_menu_tweet, menu);
}
@Override
protected void onResume() {
super.onResume();
invalidateOptionsMenu();
}
private void updateActionModeTitle(ActionMode in_action_mode) {
int tmp_count;
TextView tmp_textview;
tmp_count = _m_list_view.getCheckedItemCount();
tmp_textview = (TextView) in_action_mode.getCustomView().findViewById(R.id.context_menu_select_tweet_textview);
tmp_textview.setText(tmp_count + " " + "Tweet" + ((tmp_count > 1) ? "s" : ""));
if (tmp_count < _m_list_view.getCount()) {
((CheckBox) in_action_mode.getCustomView().findViewById(R.id.context_menu_select_tweet_checkbox)).setChecked(false);
}
else {
((CheckBox) in_action_mode.getCustomView().findViewById(R.id.context_menu_select_tweet_checkbox)).setChecked(true);
}
}
public void onSelectAllTweet(View in_view) {
int ii;
boolean tmp_checked;
tmp_checked = ((CheckBox) in_view).isChecked();
if (tmp_checked) {
for (ii=0; ii<_m_list_view.getCount(); ii++) {
_m_list_view.setItemChecked(ii, true);
}
}
else {
for (ii=0; ii<_m_list_view.getCount(); ii++) {
_m_list_view.setItemChecked(ii, false);
}
}
}
private List<Tweet> genererTweets(){
List<Tweet> tweets = new ArrayList<Tweet>();
tweets.add(new Tweet(Color.BLACK, "Florent", "Mon premier tweet !"));
tweets.add(new Tweet(Color.BLUE, "Kevin", "C'est ici que ça se passe !"));
tweets.add(new Tweet(Color.GREEN, "Logan", "Que c'est beau..."));
tweets.add(new Tweet(Color.RED, "Mathieu", "Il est quelle heure ??"));
tweets.add(new Tweet(Color.GRAY, "Willy", "On y est presque"));
return tweets;
}
我的CustomAdapter:
public class TweetAdapter extends BaseAdapter {
private int _m_choice_mode;
private List<Tweet> _m_tweet_list;
private Context _m_context;
//tweets est la liste des models à afficher
public TweetAdapter(Context context, List<Tweet> tweets, int in_choice_mode) {
_m_choice_mode = in_choice_mode;
_m_tweet_list = tweets;
_m_context = context;
}
public void setChoiseMode(int in_choise_mode) {
_m_choice_mode = in_choise_mode;
}
@Override
public int getCount() {
return _m_tweet_list.size();
}
@Override
public Tweet getItem(int position) {
return _m_tweet_list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(_m_context).inflate(R.layout.row_tweet,parent, false);
}
TweetViewHolder viewHolder = (TweetViewHolder) convertView.getTag();
if(viewHolder == null){
viewHolder = new TweetViewHolder();
viewHolder.m_selector = (ImageView) convertView.findViewById(R.id.selector);
viewHolder.pseudo = (TextView) convertView.findViewById(R.id.pseudotweet);
viewHolder.text = (TextView) convertView.findViewById(R.id.texttweet);
viewHolder.avatar = (ImageView) convertView.findViewById(R.id.avatartweet);
convertView.setTag(viewHolder);
}
//getItem(position) va récupérer l'item [position] de la List<Tweet> tweets
Tweet tweet = getItem(position);
//il ne reste plus qu'à remplir notre vue
viewHolder.pseudo.setText(tweet.getPseudo());
viewHolder.text.setText(tweet.getText());
viewHolder.avatar.setImageDrawable(new ColorDrawable(tweet.getColor()));
if (_m_choice_mode == ListView.CHOICE_MODE_MULTIPLE_MODAL) {
viewHolder.m_selector.setVisibility(View.VISIBLE);
}
else {
viewHolder.m_selector.setVisibility(View.GONE);
}
return convertView;
}
private class TweetViewHolder{
public ImageView m_selector;
public TextView pseudo;
public TextView text;
public ImageView avatar;
}
当ListView处于CHOICE_MODE_MULTIPLE_MODAL
模式时取消选中所有项目时出现问题(当我们长时间点击项目时设置此模式)。当我取消选中上次检查的项目时,onDestroyActionMode
方法(更准确地说是行_m_list_view.setChoiceMode(...)
)会给我一个错误,应用程序崩溃而没有消息。
日志:
10-25 15:38:43.396 31949-31949/com.example.vvigie.testappactires D/Error: ERR: stack=java.lang.StackOverflowError: stack size 8MB
at android.support.v7.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:82)
at android.widget.AbsListView.setChoiceMode(AbsListView.java:1603)
at com.example.vvigie.testappactires.MainActivity$3.onDestroyActionMode(MainActivity.java:135)
at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:8355)
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3963)
at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:179)
at android.support.v7.app.AppCompatDelegateImplV9$ActionModeCallbackWrapperV9.onDestroyActionMode(AppCompatDelegateImplV9.java:1806)
at android.support.v7.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:1007)
at android.support.v7.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:82)
at android.widget.AbsListView.setChoiceMode(AbsListView.java:1603)
at com.example.vvigie.testappactires.MainActivity$3.onDestroyActionMode(MainActivity.java:135)
at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:8355)
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3963)
at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:179)
at android.support.v7.app.AppCompatDelegateImplV9$ActionModeCallbackWrapperV9.onDestroyActionMode(AppCompatDelegateImplV9.java:1806)
at android.support.v7.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:1007)
at android.support.v7.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:82)
at android.widget.AbsListView.setChoiceMode(AbsListView.java:1603)
at com.example.vvigie.testappactires.MainActivity$3.onDestroyActionMode(MainActivity.java:135)
at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:8355)
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3963)
at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:179)
at android.support.v7.app.AppCompatDelegateImplV9$ActionModeCallbackWrapperV9.onDestroyActionMode(AppCompatDelegateImplV9.java:1806)
at android.support.v7.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:1007)
at android.support.v7.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:82)
at android.widget.AbsListView.setChoiceMode(AbsListView.java:1603)
at com.example.vvigie.testappactires.MainActivity$3.onDestroyActionMode(MainActivity.java:135)
at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:8355)
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3963)
at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:179)
at android.support.v7.app.AppCompatDelegateImplV9$ActionModeCallbackWrapperV9.onDestroyActionMode(AppCompatDelegateImplV9.java:1806)
at android.support.v7.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:1007)
at android.support.v7.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:82)
at android.widget.AbsListView.setChoiceMode(AbsListView.java:1603)
at com.example.vvigie.testappactires.MainActivity$3.onDestroyActionMode(MainActivity.java:135)
at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:8355)
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3963)
at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:179)
at android.support.v7.app.AppCom
我不明白为什么这条线会带来这个错误...你能帮帮我吧。 抱歉,我的“法语”英语。
编辑:解决方案在评论中,谢谢!
答案 0 :(得分:1)
你有一个无限的呼叫循环。此行_m_list_view.setChoiceMode(ListView.CHOICE_MODE_NONE);
会导致AbsListView.MultiChoiceModeListener#onDestroyActionMode()
被调用,再次调用第一行等等。
摘要是您不应该在_m_list_view.setChoiceMode()
中致电onDestroyActionMode()
,或者至少不需要将其设置为NONE
。