我希望以前有人见过这个问题。我有一个列表视图,其中所有元素都有一个复选框。除了有一个不可选择的复选框(无法检查和取消选中)之外,这一切都运行良好。它不是列表中的第一项,并且所有设备上都没有问题。适用于三星S3,但在Nexus 6P上有问题。
经过一番调查后,我打开了“显示布局界限”。在开发人员选项中。这是我看到一些非常有趣的东西,无法点击的元素没有画出任何界限。在下面的示例中,' Bar Tunes'是不可选择的。
有没有人知道为什么会这样。这是布局文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingRight="@dimen/list_10sp"
android:gravity="center_vertical"
android:id="@+id/listRow"
android:background="@color/GreyLight">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<CheckBox
android:layout_width="@dimen/list_40sp"
android:layout_height="@dimen/list_40sp"
android:layout_marginLeft="@dimen/list_5sp"
android:checked="true"
android:id="@+id/selectedCheckbox"
android:button="@drawable/button_checkbox_image"
android:layout_gravity="center_vertical"/>
<ImageView
android:id="@+id/connectedIcon"
android:src="@drawable/tick_raw"
android:adjustViewBounds="true"
android:layout_width="@dimen/list_20sp"
android:layout_height="@dimen/list_20sp"
android:layout_marginLeft="@dimen/list_20sp"/>
</FrameLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textBackground">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_weight="1"
android:paddingRight="@dimen/list_10sp"
android:paddingTop="@dimen/list_5sp"
android:paddingBottom="@dimen/list_5sp"
android:clickable="true"
android:id="@+id/searchList"
android:background="@drawable/button_list_item"
android:layout_height="wrap_content">
<com.hdms.manager.Drawable.NightlifeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="List Name"
android:textSize="@dimen/list_text_size"
android:textStyle="bold"
android:id="@+id/listName"
android:singleLine="true"
android:ellipsize="middle"/>
<com.hdms.manager.Drawable.NightlifeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/playlist_neg_2sp"
android:text="(User Friendly Name)"
android:textSize="@dimen/playlist_text_size"
android:singleLine="true"
android:id="@+id/friendlyName" />
<com.hdms.manager.Drawable.NightlifeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="List Description"
android:textSize="@dimen/list_text_size_smaller"
android:singleLine="true"
android:id="@+id/listDescription" />
</LinearLayout>
<ImageButton
android:layout_width="@dimen/playlist_40sp"
android:layout_height="@dimen/playlist_40sp"
android:padding="@dimen/account_2sp"
android:layout_marginLeft="@dimen/account_5sp"
android:layout_gravity="center"
android:visibility="gone"
android:scaleType="fitCenter"
android:id="@+id/crowdDJButton"
android:src="@drawable/crowddj_icon"
android:background="@drawable/button_background_green"/>
<ImageButton
android:layout_width="@dimen/playlist_40sp"
android:layout_height="@dimen/playlist_40sp"
android:src="@drawable/icon_nm"
android:layout_gravity="center"
android:visibility="gone"
android:layout_marginLeft="@dimen/account_5sp"
android:scaleType="fitCenter"
android:tint="@color/White"
android:background="@drawable/button_background_green"
android:padding="@dimen/account_2sp"
android:id="@+id/musicSystemButton"/>
<ImageView
android:layout_width="@dimen/playlist_20sp"
android:layout_height="@dimen/playlist_20sp"
android:padding="@dimen/playlist_2sp"
android:layout_marginRight="@dimen/player_5sp"
android:layout_gravity="center_vertical"
android:visibility="gone"
android:id="@+id/crowdDJSearchable"
android:background="@color/StormGreen"
android:src="@drawable/crowddj_icon"/>
<com.hdms.manager.Drawable.NightlifeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/White"
android:text="0"
android:textSize="@dimen/list_text_size_smaller"
android:minWidth="@dimen/list_45sp"
android:minHeight="@dimen/list_25sp"
android:singleLine="true"
android:ellipsize="marquee"
android:id="@+id/songCount"
android:layout_gravity="center_vertical"
android:background="@drawable/border_rounded_darkgrey"/>
<ImageView
android:id="@+id/dot"
android:src="@drawable/dot_dot_dot"
android:adjustViewBounds="true"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:layout_marginRight="@dimen/account_10sp"
android:layout_width="@dimen/list_20sp"
android:layout_height="@dimen/list_20sp"/>
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/list_1sp"
android:background="@drawable/verticalline"/>
</LinearLayout>
有关如何修复或追踪此问题的任何建议?感谢
这是一些适配器代码,因为它超过了帖子的文本限制。
@Override
public View getChildView(int groupPosition, int position, boolean isLastChild, View aView, ViewGroup parent)
{
final Object item = getChild(groupPosition, position);
switch (mMode)
{
case Spotify:
if (aView == null || aView.getId() != R.id.spotifyRow)
aView = mLayoutInflater.inflate(R.layout.list_spotify_item, null);
aView.setTag("" + position);
setupSpotifyLists(aView, item);
break;
case SelectionSets:
if (aView == null || aView.getId() != R.id.selection)
aView = mLayoutInflater.inflate(R.layout.selection_item, null);
setupSelectionSets(aView, (HDMSLiveSession.SelectionSet) item);
break;
case SelectionSet:
if (aView == null || aView.getId() != R.id.selection)
aView = mLayoutInflater.inflate(R.layout.selection_item, null);
setupSelectionSet(aView, (String) item);
break;
default:
HDMSLiveSession.SystemLists data = HDMSLiveSession.getInstance().getMLData((String) item);
if (data != null || item.equals(gSpotifyList))
{
if (aView == null || aView.getId() != R.id.listRow)
aView = mLayoutInflater.inflate(R.layout.list_item, null);
setupList(data, aView, (String) item);
}
else
{
if (aView == null || aView.getId() != R.id.list_sub)
aView = mLayoutInflater.inflate(R.layout.lists_subheading, null);
setupSubHeading((String) item, aView);
}
break;
}
return aView;
}
private void setupList(final HDMSLiveSession.SystemLists aData, View aView, final String aList)
{
LinearLayout textBackground = (LinearLayout)aView.findViewById(R.id.textBackground);
if (Build.VERSION.SDK_INT >= 16)
textBackground.setBackground(aView.getResources().getDrawable(R.drawable.list_background));
else
textBackground.setBackgroundDrawable(aView.getResources().getDrawable(R.drawable.list_background));
LinearLayout listSearch = (LinearLayout)aView.findViewById(R.id.searchList);
listSearch.setClickable(true);
final boolean ambient = aData != null && (aData.mGroup.equals("Ambient") || aData.mGroup.equals("User Ambient"));
final boolean karaoke = aData != null && (aData.mGroup.toUpperCase().equals("KARAOKE") || aList.contains("KARAOKE"));
listSearch.setOnClickListener(new NightlifeOnClickListener()
{
@Override
public void onClick(View aView)
{
super.onClick(aView);
if (mListener != null)
mListener.onListSearch(aList, ambient, karaoke, aData);
}
});
// the user friendly name (or id if no friendly name is available)
TextView name = (TextView)aView.findViewById(R.id.listName);
String count = aData == null && MusicPreview.getInstance().isLoggedIn() ? (MusicPreview.getInstance().getLinkedCount() >= 0 ? " - " + MusicPreview.getInstance().getLinkedCount() : " - N/A") : "";
SpannableString content = new SpannableString(aList + count);
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
if (aData == null)
name.setText(content);
else if(aData.mUserName != null && !aData.mUserName.isEmpty())
name.setText(aData.mUserName);
else
name.setText(aList);
// description of the list
TextView description = (TextView)aView.findViewById(R.id.listDescription);
String descriptionText = aData != null ? aData.mDescription :
(MusicPreview.getInstance().isLoggedIn() && MusicPreview.getInstance().getLinkedTitle() != null && !MusicPreview.getInstance().getLinkedTitle().isEmpty() ?
MusicPreview.getInstance().getLinkedTitle() : "No Selected Spotify List.");
description.setText(descriptionText);
// id if friendly name is available)
TextView userName = (TextView)aView.findViewById(R.id.friendlyName);
boolean spotify = aData != null && aData.mGroup.toUpperCase().equals("SPOTIFY");
if (aData != null && aData.mUserName != null && !aData.mUserName.isEmpty() && !spotify)
{
userName.setVisibility(View.VISIBLE);
userName.setText("( " + aList + " )");
}
else
userName.setVisibility(View.GONE);
ImageView tick = (ImageView)aView.findViewById(R.id.connectedIcon);
boolean listLoaded;
if (ambient)
{
listLoaded = HDMSLiveSession.getInstance().isAmbientListLoaded(aList);
}
else
{
listLoaded = HDMSLiveSession.getInstance().isSelectionsOnly() ? HDMSLiveSession.getInstance().isSelectionList(aList) : HDMSLiveSession.getInstance().isListLoaded(aList);
}
ImageView dot = (ImageView)aView.findViewById(R.id.dot);
if (aData == null)
{
tick.setVisibility(View.GONE);
dot.setVisibility(View.VISIBLE);
dot.setColorFilter(aView.getResources().getColor(R.color.Black));
dot.setClickable(true);
dot.setOnClickListener(new NightlifeOnClickListener()
{
@Override public void onClick(View aView)
{
super.onClick(aView);
if (mListener != null)
mListener.onSelectSpotifyList();
}
});
}
else
{
dot.setVisibility(View.GONE);
tick.setVisibility(listLoaded ? View.VISIBLE : View.GONE);
tick.setImageResource(R.drawable.tick_raw);
tick.setColorFilter(aView.getResources().getColor(R.color.StormGreen));
}
CheckBox checkBox = (CheckBox)aView.findViewById(R.id.selectedCheckbox);
checkBox.setEnabled(mEnableCheckBoxes && isSelectable(aData, aList) && !isInSelectionSet(aList));
Log.e("List", aList + " " + checkBox.isEnabled());
mIgnore = true;
if (mListener != null)
checkBox.setChecked(mListener.isSelected(aList));
else
checkBox.setChecked(false);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton aCompoundButton, boolean aChecked)
{
Log.e("List", aList + " onCheckedChanged: " + aChecked);
if (mListener != null && !mIgnore)
mListener.onListSelected(aList, aData, aChecked);
}
});
mIgnore = false;
if (!mShowLoadingCheckbox)
{
tick.setVisibility(View.GONE);
dot.setVisibility(View.GONE);
checkBox.setVisibility(View.GONE);
}
TextView songCount = (TextView)aView.findViewById(R.id.songCount);
if (aData != null)
songCount.setText(String.valueOf(aData.mSongCount));
songCount.setVisibility(aData != null ? View.VISIBLE : View.GONE);
if (HDMSLiveSession.getInstance().isSelectionsOnly())
{
if (listLoaded)
songCount.setTextColor(songCount.getResources().getColor(R.color.White));
else
songCount.setTextColor(songCount.getResources().getColor(R.color.Grey));
}
else
songCount.setTextColor(songCount.getResources().getColor(R.color.White));
// crowdDJ Icon
boolean discovery = aData != null && HDMSLiveSession.getInstance().isDiscoveryList(aData.mName);
View searchable = aView.findViewById(R.id.crowdDJSearchable);
searchable.setVisibility(/*spotify && */discovery ? View.VISIBLE : View.GONE);
}
private boolean isSelectable(HDMSLiveSession.SystemLists aData, String aList)
{
boolean isSpotifyList = aData == null;
boolean selectable = isSpotifyList && MusicPreview.getInstance().isLoggedIn();
if (!isSpotifyList)
{
boolean useList = aData.mGroup.toUpperCase().equals("UNKNOWN");
boolean negative = aData.mGroup.toLowerCase().equals("negative");
boolean deleted = aList.toUpperCase().equals("DELETED") || aList.toUpperCase().equals("TAGGED") || aList.toUpperCase().equals("HIDDEN");
boolean ambient = aData.mGroup.toLowerCase().equals("ambient") || aData.mGroup.toLowerCase().equals("user ambient");
boolean karaoke = aData.mGroup.toUpperCase().equals("KARAOKE");
selectable |= !(!aData.mLoadable && !useList || negative || deleted) && !karaoke;
}
return selectable;
}
private boolean isInSelectionSet(String aList)
{
return HDMSLiveSession.getInstance().getVersionID() > 3.909 && HDMSLiveSession.getInstance().isSelectionsOnly() && !HDMSLiveSession.getInstance().isSelectionList(aList);
}
这些是相关功能。列表视图是一个ExpandableListView,如果有帮助的话。
此问题似乎只发生在Android 7.0及更高版本上。我也在Android 8上证实了这一点。
答案 0 :(得分:0)
因为您有一些物品没有使用convertView
给您的ListView
。下次您获得该视图并使用它时,它将是这样。
当您使用其他视图工具时,建议使用getViewTypeCount()
和getItemViewType()
。
答案 1 :(得分:0)
所以我找到了解决此问题的方法。单元格的位置设置为0,0。 我已经重写了ListView的dispatchTouchEvent,部分代码如下。
case ACTION_UP:
// HACK: This is a fix for Android setting some views position to 0,0
if (mPassOnTouch)
{
View view = getChild(aMotionEvent);
if (view != null && isBadView(view))
{
int[] location = new int[2];
getLocationInWindow(location);
List<View> views = findClickableViews(view, new Vector<View>());
for (View subView: views)
{
int[] position = calculatePosition(subView, view, location);
if (isWithIn(subView, position, (int)aMotionEvent.getRawX(), (int)aMotionEvent.getRawY()))
{
subView.performClick();
break;
}
}
}
}
break;
代码检查运动事件位置下的视图。 (获取视图位置所需的所有数据均可用,但是函数getLocationInWindow或getLocationOnScreen错误)。然后,我检查视图位置是否为0,0。然后找到所有可单击的子视图,并手动调整其位置。
需要执行点击,因为onTouchEvent需要一个“正确”的位置。