onItemCheckedStateChanged 调用了两次
onItemCheckedStateChanged called twice
我遇到了一个奇怪的问题,我不确定具体是怎么回事。我设法通过手动检查列表视图中第一个被检查的项目是否是第二次调用的项目来绕过这个问题。
问题是,当用户长按列表视图项(适配器内部的 onlongclicklistener)时,会检查列表视图项。项目释放后(长按释放),项目设置为 isChecked=false。我不知道是什么导致了这个问题。如果我理解正确,setMultiChoiceModeListener 有它自己的 onlongclick 侦听器被调用。有没有办法覆盖它并实现与大多数应用程序相同的功能(长按启动 selection 程序)?
适配器点击侦听器
vi.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.d("test abc", "ovo je krenulo");
((MainActivity) mContext).list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
((MainActivity) mContext).lvPos = position;
((MainActivity) mContext).lvPosChecked = true;
if(!((MainActivity) mContext).ListSelectionInProgress)
{
((MainActivity) mContext).ListSelectionInProgress = true;
}
if(!((MainActivity) mContext).list.isItemChecked(position))
{
((MainActivity) mContext).list.setItemChecked(position, true);
}
else
{
((MainActivity) mContext).list.setItemChecked(position, false);
}
return true;
}
});
vi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("CL", "State called");
if(((MainActivity) mContext).ListSelectionInProgress)
{
((MainActivity) mContext).lvPos = position;
((MainActivity) mContext).lvPos = -1;
if(!((MainActivity) mContext).list.isItemChecked(position))
{
((MainActivity) mContext).list.setItemChecked(position, true);
}
else
{
((MainActivity) mContext).list.setItemChecked(position, false);
}
Log.d("State", Integer.toString(((MainActivity) mContext).list.getCheckedItemCount()));
}
}
});
setMultiChoiceModeListener
list.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if(position == lvPos && checked != lvPosChecked)
{
list.setItemChecked(position, true);
}
mode.setTitle(Integer.toString(list.getCheckedItemCount()));
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
ListSelectionInProgress = true;
MenuInflater inflater = mode.getMenuInflater();
if(SUBLEVEL == 1) {
inflater.inflate(R.menu.action_mode_add, menu);
}
else if(SUBLEVEL == 5) // SATNICA
{
inflater.inflate(R.menu.action_mode_remove, menu);
}
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int c = 0;
switch(item.getItemId())
{
case R.id.selAll:
for(int i=0;i<list.getAdapter().getCount();i++) {
list.setItemChecked(i, true);
}
break;
case R.id.addSch:
c = 0;
for(int i=0;i<list.getAdapter().getCount();i++)
{
if(list.isItemChecked(i))
{
addToSchedule(i);
c++;
}
}
if(c > 1)
{
Toast.makeText(MainActivity.this, R.string.addToMyScheduleSuccessPlural, Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, R.string.addToMyScheduleSuccess, Toast.LENGTH_SHORT).show();
}
mode.finish();
break;
case R.id.remSch:
c = 0;
if(list.getAdapter() != null)
{
for(int i=0;i<list.getAdapter().getCount();i++)
{
if(list.isItemChecked(i))
{
removeFromSchedule(i);
c++;
}
}
if(c > 1) {
Toast.makeText(MainActivity.this, R.string.removeFromMyScheduleSuccessPlural, Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, R.string.removeFromMyScheduleSuccess, Toast.LENGTH_SHORT).show();
}
loadMySchedule();
mode.finish();
}
break;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
ListSelectionInProgress = false;
}
});
listview_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="@+id/classItemLV"
android:background="@drawable/list_row"
android:minHeight="80dp"
android:descendantFocusability="blocksDescendants"
android:elevation="2dp">
<RelativeLayout
android:layout_width="16dp"
android:layout_height="wrap_content"
android:id="@+id/lday"
android:layout_alignParentStart="true"
android:layout_marginStart="10dp"
android:layout_centerVertical="true"
android:background="@color/colorPrimary"
android:minWidth="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="P\nO\nN"
android:id="@+id/DAY1"
android:layout_alignParentStart="false"
android:textColor="#fff"
android:textSize="15sp"
android:layout_margin="2dp"
android:textAlignment="center"
android:layout_centerInParent="true" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lTime"
android:layout_alignWithParentIfMissing="false"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:layout_toEndOf="@+id/lday">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="10"
android:id="@+id/timeFrom"
android:textColor="@color/colorLV3Dark"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="false"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="12"
android:id="@+id/timeTo"
android:textColor="@color/colorLV3Dark"
android:layout_below="@+id/timeFrom" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lInfo"
android:layout_marginStart="10dp"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/lTime">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Analiza financijskih izvještaja"
android:id="@+id/className"
android:textColor="@color/colorLV3Dark"
android:layout_alignParentStart="true"
android:layout_marginEnd="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="prof. dr. sc. Ivan Ivić"
android:id="@+id/classTutor"
android:focusableInTouchMode="false"
android:textColor="@color/colorLV3"
android:layout_below="@+id/className" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="PREDAVANJE - DV41"
android:id="@+id/classTypePlace"
android:textIsSelectable="false"
android:textColor="@color/colorLV3"
android:textSize="12sp"
android:layout_below="@+id/classTutor" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Datum: 5.10.-25.1."
android:id="@+id/classDate"
android:clickable="false"
android:textSize="12sp"
android:textColor="@color/colorLV3"
android:layout_alignParentEnd="true"
android:layout_alignBottom="@+id/classTypePlace"
android:layout_marginEnd="10dp" />
</RelativeLayout>
</RelativeLayout>
我已尽我所能调试代码,并且注意到以下内容:
1) onItemCheckedStateChanged 在长按松开后被调用
2) OnClick 被正常调用并且完全不受 longclick 侦听器的影响(除了通过 public 布尔变量启用 selection 槽)
3) 如果我将手指移出视图或移到视图的另一侧,同时按住触摸事件,它会保持选中状态
4) 如果我快速 select 一个不同的项目,两者都保持选中状态
似乎有什么东西覆盖了我的列表视图项目的选中状态。可能是什么?
摸索了两天,终于找到了解决办法。我正在处理适配器内部的正常点击和长时间点击。
好像
setMultiChoiceModeListener
自行处理这两种点击,无需手动处理这两种类型的点击。我希望我早点在某个地方读到它。我希望这个答案对以后的人也有帮助。
我遇到了一个奇怪的问题,我不确定具体是怎么回事。我设法通过手动检查列表视图中第一个被检查的项目是否是第二次调用的项目来绕过这个问题。
问题是,当用户长按列表视图项(适配器内部的 onlongclicklistener)时,会检查列表视图项。项目释放后(长按释放),项目设置为 isChecked=false。我不知道是什么导致了这个问题。如果我理解正确,setMultiChoiceModeListener 有它自己的 onlongclick 侦听器被调用。有没有办法覆盖它并实现与大多数应用程序相同的功能(长按启动 selection 程序)?
适配器点击侦听器
vi.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.d("test abc", "ovo je krenulo");
((MainActivity) mContext).list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
((MainActivity) mContext).lvPos = position;
((MainActivity) mContext).lvPosChecked = true;
if(!((MainActivity) mContext).ListSelectionInProgress)
{
((MainActivity) mContext).ListSelectionInProgress = true;
}
if(!((MainActivity) mContext).list.isItemChecked(position))
{
((MainActivity) mContext).list.setItemChecked(position, true);
}
else
{
((MainActivity) mContext).list.setItemChecked(position, false);
}
return true;
}
});
vi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("CL", "State called");
if(((MainActivity) mContext).ListSelectionInProgress)
{
((MainActivity) mContext).lvPos = position;
((MainActivity) mContext).lvPos = -1;
if(!((MainActivity) mContext).list.isItemChecked(position))
{
((MainActivity) mContext).list.setItemChecked(position, true);
}
else
{
((MainActivity) mContext).list.setItemChecked(position, false);
}
Log.d("State", Integer.toString(((MainActivity) mContext).list.getCheckedItemCount()));
}
}
});
setMultiChoiceModeListener
list.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if(position == lvPos && checked != lvPosChecked)
{
list.setItemChecked(position, true);
}
mode.setTitle(Integer.toString(list.getCheckedItemCount()));
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
ListSelectionInProgress = true;
MenuInflater inflater = mode.getMenuInflater();
if(SUBLEVEL == 1) {
inflater.inflate(R.menu.action_mode_add, menu);
}
else if(SUBLEVEL == 5) // SATNICA
{
inflater.inflate(R.menu.action_mode_remove, menu);
}
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int c = 0;
switch(item.getItemId())
{
case R.id.selAll:
for(int i=0;i<list.getAdapter().getCount();i++) {
list.setItemChecked(i, true);
}
break;
case R.id.addSch:
c = 0;
for(int i=0;i<list.getAdapter().getCount();i++)
{
if(list.isItemChecked(i))
{
addToSchedule(i);
c++;
}
}
if(c > 1)
{
Toast.makeText(MainActivity.this, R.string.addToMyScheduleSuccessPlural, Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, R.string.addToMyScheduleSuccess, Toast.LENGTH_SHORT).show();
}
mode.finish();
break;
case R.id.remSch:
c = 0;
if(list.getAdapter() != null)
{
for(int i=0;i<list.getAdapter().getCount();i++)
{
if(list.isItemChecked(i))
{
removeFromSchedule(i);
c++;
}
}
if(c > 1) {
Toast.makeText(MainActivity.this, R.string.removeFromMyScheduleSuccessPlural, Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, R.string.removeFromMyScheduleSuccess, Toast.LENGTH_SHORT).show();
}
loadMySchedule();
mode.finish();
}
break;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
ListSelectionInProgress = false;
}
});
listview_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="@+id/classItemLV"
android:background="@drawable/list_row"
android:minHeight="80dp"
android:descendantFocusability="blocksDescendants"
android:elevation="2dp">
<RelativeLayout
android:layout_width="16dp"
android:layout_height="wrap_content"
android:id="@+id/lday"
android:layout_alignParentStart="true"
android:layout_marginStart="10dp"
android:layout_centerVertical="true"
android:background="@color/colorPrimary"
android:minWidth="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="P\nO\nN"
android:id="@+id/DAY1"
android:layout_alignParentStart="false"
android:textColor="#fff"
android:textSize="15sp"
android:layout_margin="2dp"
android:textAlignment="center"
android:layout_centerInParent="true" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lTime"
android:layout_alignWithParentIfMissing="false"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:layout_toEndOf="@+id/lday">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="10"
android:id="@+id/timeFrom"
android:textColor="@color/colorLV3Dark"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="false"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="12"
android:id="@+id/timeTo"
android:textColor="@color/colorLV3Dark"
android:layout_below="@+id/timeFrom" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lInfo"
android:layout_marginStart="10dp"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/lTime">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Analiza financijskih izvještaja"
android:id="@+id/className"
android:textColor="@color/colorLV3Dark"
android:layout_alignParentStart="true"
android:layout_marginEnd="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="prof. dr. sc. Ivan Ivić"
android:id="@+id/classTutor"
android:focusableInTouchMode="false"
android:textColor="@color/colorLV3"
android:layout_below="@+id/className" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="PREDAVANJE - DV41"
android:id="@+id/classTypePlace"
android:textIsSelectable="false"
android:textColor="@color/colorLV3"
android:textSize="12sp"
android:layout_below="@+id/classTutor" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Datum: 5.10.-25.1."
android:id="@+id/classDate"
android:clickable="false"
android:textSize="12sp"
android:textColor="@color/colorLV3"
android:layout_alignParentEnd="true"
android:layout_alignBottom="@+id/classTypePlace"
android:layout_marginEnd="10dp" />
</RelativeLayout>
</RelativeLayout>
我已尽我所能调试代码,并且注意到以下内容:
1) onItemCheckedStateChanged 在长按松开后被调用
2) OnClick 被正常调用并且完全不受 longclick 侦听器的影响(除了通过 public 布尔变量启用 selection 槽)
3) 如果我将手指移出视图或移到视图的另一侧,同时按住触摸事件,它会保持选中状态
4) 如果我快速 select 一个不同的项目,两者都保持选中状态
似乎有什么东西覆盖了我的列表视图项目的选中状态。可能是什么?
摸索了两天,终于找到了解决办法。我正在处理适配器内部的正常点击和长时间点击。
好像
setMultiChoiceModeListener
自行处理这两种点击,无需手动处理这两种类型的点击。我希望我早点在某个地方读到它。我希望这个答案对以后的人也有帮助。