Android ListView - Unclickable Checkbox

时间:2017-12-01 01:37:14

标签: android listview checkbox

我希望以前有人见过这个问题。我有一个列表视图,其中所有元素都有一个复选框。除了有一个不可选择的复选框(无法检查和取消选中)之外,这一切都运行良好。它不是列表中的第一项,并且所有设备上都没有问题。适用于三星S3,但在Nexus 6P上有问题。

经过一番调查后,我打开了“显示布局界限”。在开发人员选项中。这是我看到一些非常有趣的东西,无法点击的元素没有画出任何界限。在下面的示例中,' Bar Tunes'是不可选择的。

Layout Bounds

有没有人知道为什么会这样。这是布局文件。

<?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上证实了这一点。

2 个答案:

答案 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需要一个“正确”的位置。