Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android ListView longClickable=";“真的”;禁用McClick侦听器_Android_Listview_Android Listview_Onclicklistener_Onlongclicklistener - Fatal编程技术网

Android ListView longClickable=";“真的”;禁用McClick侦听器

Android ListView longClickable=";“真的”;禁用McClick侦听器,android,listview,android-listview,onclicklistener,onlongclicklistener,Android,Listview,Android Listview,Onclicklistener,Onlongclicklistener,我的ListView有问题。我想在正常单击时显示一个上下文操作栏和列表项的详细信息片段。 但是如果我在列表项的xml布局中设置longClickable=“true”,则不会触发onItemClickListener;如果我删除该行,则可以单击该项,但现在longclick无法处理NullPointerException。 我现在花了几个小时来解决这个问题,例如在布局中使用安卓:genderantfocusability=“blocksDescendants”,或者在列表项中的元素上使用focu

我的ListView有问题。我想在正常单击时显示一个上下文操作栏和列表项的详细信息片段。 但是如果我在列表项的xml布局中设置longClickable=“true”,则不会触发onItemClickListener;如果我删除该行,则可以单击该项,但现在longclick无法处理NullPointerException。 我现在花了几个小时来解决这个问题,例如在布局中使用安卓:genderantfocusability=“blocksDescendants”,或者在列表项中的元素上使用focusability=“false”。什么都不管用。这里有一些代码

mItemAdapter = new CustomItemAdapter(getActivity(), this, mItemList);
mListView.setAdapter(mItemAdapter);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setOnItemClickListener(this);
mListView.setOnItemLongClickListener(this);
我正在使用带有自定义对象的自定义适配器类来填充我的列表

public class CustomItemAdapter extends ArrayAdapter<Item>
公共类CustomItemAdapter扩展了ArrayAdapter
我应该避免在那里设置任何侦听器吗

这是我的布局的根元素:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:background="@drawable/list_item_shape"
    android:descendantFocusability="blocksDescendants"
    android:longClickable="true"
    android:clickable="true"
    android:orientation="vertical" >


感谢您的帮助。

当我想要实现与您描述的完全相同的目标时,我使用以下代码:

/*
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.maddogs.mymoney.utils;

import java.util.HashSet;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.util.Pair;
import android.util.SparseBooleanArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ListView;

/**
 * Utilities for handling multiple selection in list views. Contains
 * functionality similar to {@link AbsListView#CHOICE_MODE_MULTIPLE_MODAL} but
 * that works with {@link ActionBarActivity} and backward-compatible action
 * bars.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MultiSelectionUtil {
    public static Controller attachMultiSelectionController(
            final ListView listView, final ActionBarActivity activity,
            final MultiChoiceModeListener listener) {
        return Controller.attach(listView, activity, listener);
    }

    @SuppressLint("NewApi")
    public static class Controller implements ActionMode.Callback,
            AdapterView.OnItemClickListener,
            AdapterView.OnItemLongClickListener {
        private Handler mHandler = new Handler();
        private ActionMode mActionMode;
        private ListView mListView = null;
        private ActionBarActivity mActivity = null;
        private MultiChoiceModeListener mListener = null;
        private HashSet<Long> mTempIdsToCheckOnRestore;
        private HashSet<Pair<Integer, Long>> mItemsToCheck;
        private AdapterView.OnItemClickListener mOldItemClickListener;

        private Controller() {
        }

        public static Controller attach(ListView listView,
                                        ActionBarActivity activity, MultiChoiceModeListener listener) {
            Controller controller = new Controller();
            controller.mListView = listView;
            controller.mActivity = activity;
            controller.mListener = listener;
            listView.setOnItemLongClickListener(controller);
            return controller;
        }

        private void readInstanceState(Bundle savedInstanceState) {
            mTempIdsToCheckOnRestore = null;
            if (savedInstanceState != null) {
                long[] checkedIds = savedInstanceState
                        .getLongArray(getStateKey());
                if (checkedIds != null && checkedIds.length > 0) {
                    mTempIdsToCheckOnRestore = new HashSet<Long>();
                    for (long id : checkedIds) {
                        mTempIdsToCheckOnRestore.add(id);
                    }
                }
            }
        }

        public void tryRestoreInstanceState(Bundle savedInstanceState) {
            readInstanceState(savedInstanceState);
            tryRestoreInstanceState();
        }

        public void finish() {
            if (mActionMode != null) {
                mActionMode.finish();
            }
        }

        public void tryRestoreInstanceState() {
            if (mTempIdsToCheckOnRestore == null
                    || mListView.getAdapter() == null) {
                return;
            }

            boolean idsFound = false;
            Adapter adapter = mListView.getAdapter();
            for (int pos = adapter.getCount() - 1; pos >= 0; pos--) {
                if (mTempIdsToCheckOnRestore.contains(adapter.getItemId(pos))) {
                    idsFound = true;
                    if (mItemsToCheck == null) {
                        mItemsToCheck = new HashSet<Pair<Integer, Long>>();
                    }
                    mItemsToCheck.add(new Pair<Integer, Long>(pos, adapter
                            .getItemId(pos)));
                }
            }

            if (idsFound) {
                // We found some IDs that were checked. Let's now restore the
                // multi-selection
                // state.
                mTempIdsToCheckOnRestore = null; // clear out this temp field
                mActionMode = mActivity.startSupportActionMode(Controller.this);
            }
        }

        public boolean saveInstanceState(Bundle outBundle) {
            // TODO: support non-stable IDs by persisting positions instead of
            // IDs
            if (mActionMode != null && mListView.getAdapter().hasStableIds()) {
                long[] checkedIds = mListView.getCheckedItemIds();
                outBundle.putLongArray(getStateKey(), checkedIds);
                return true;
            }

            return false;
        }

        private String getStateKey() {
            return MultiSelectionUtil.class.getSimpleName() + "_"
                    + mListView.getId();
        }

        @Override
        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            if (mListener.onCreateActionMode(actionMode, menu)) {
                mActionMode = actionMode;
                mOldItemClickListener = mListView.getOnItemClickListener();
                mListView.setOnItemClickListener(Controller.this);
                mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
                mHandler.removeCallbacks(mSetChoiceModeNoneRunnable);

                if (mItemsToCheck != null) {
                    for (Pair<Integer, Long> posAndId : mItemsToCheck) {
                        mListView.setItemChecked(posAndId.first, true);
                        mListener.onItemCheckedStateChanged(mActionMode,
                                posAndId.first, posAndId.second, true);
                    }
                }
                return true;
            }
            return false;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
            if (mListener.onPrepareActionMode(actionMode, menu)) {
                mActionMode = actionMode;
                return true;
            }
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode actionMode,
                                           MenuItem menuItem) {
            return mListener.onActionItemClicked(actionMode, menuItem);
        }

        @Override
        public void onDestroyActionMode(ActionMode actionMode) {
            mListener.onDestroyActionMode(actionMode);
            SparseBooleanArray checkedPositions = mListView
                    .getCheckedItemPositions();
            if (checkedPositions != null) {
                for (int i = 0; i < checkedPositions.size(); i++) {
                    mListView.setItemChecked(checkedPositions.keyAt(i), false);
                }
            }
            mListView.setOnItemClickListener(mOldItemClickListener);
            mActionMode = null;
            mHandler.post(mSetChoiceModeNoneRunnable);
        }

        private Runnable mSetChoiceModeNoneRunnable = new Runnable() {
            @Override
            public void run() {
                mListView.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
            }
        };

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view,
                                int position, long id) {
            boolean checked = mListView.isItemChecked(position);
            mListener.onItemCheckedStateChanged(mActionMode, position, id,
                    checked);

            int numChecked = 0;
            SparseBooleanArray checkedItemPositions = mListView
                    .getCheckedItemPositions();
            if (checkedItemPositions != null) {
                for (int i = 0; i < checkedItemPositions.size(); i++) {
                    numChecked += checkedItemPositions.valueAt(i) ? 1 : 0;
                }
            }

            if (numChecked <= 0) {
                mActionMode.finish();
            }
        }

        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, View view,
                                       int position, long id) {
            if (mActionMode != null) {
                return false;
            }

            mItemsToCheck = new HashSet<Pair<Integer, Long>>();
            mItemsToCheck.add(new Pair<Integer, Long>(position, id));
            mActionMode = mActivity.startSupportActionMode(Controller.this);
            return true;
        }
    }

    /**
     * @see android.widget.AbsListView.MultiChoiceModeListener
     */
    public static interface MultiChoiceModeListener extends ActionMode.Callback {
        /**
         * @see android.widget.AbsListView.MultiChoiceModeListener#onItemCheckedStateChanged(android.view.ActionMode,
         * int, long, boolean)
         */
        public void onItemCheckedStateChanged(ActionMode mode, int position,
                                              long id, boolean checked);
    }
}
/*
*版权所有2012谷歌公司。
*
*根据Apache许可证2.0版(以下简称“许可证”)获得许可;
*除非遵守许可证,否则不得使用此文件。
*您可以通过以下方式获得许可证副本:
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*除非适用法律要求或书面同意,软件
*根据许可证进行的分发是按“原样”进行分发的,
*无任何明示或暗示的保证或条件。
*请参阅许可证以了解管理权限和权限的特定语言
*许可证下的限制。
*/
包com.maddogs.mymoney.utils;
导入java.util.HashSet;
导入android.annotation.SuppressLint;
导入android.annotation.TargetApi;
导入android.os.Build;
导入android.os.Bundle;
导入android.os.Handler;
导入android.support.v7.app.ActionBarActivity;
导入android.support.v7.view.ActionMode;
导入android.util.Pair;
导入android.util.SparseBooleanArray;
导入android.view.Menu;
导入android.view.MenuItem;
导入android.view.view;
导入android.widget.AbsListView;
导入android.widget.Adapter;
导入android.widget.AdapterView;
导入android.widget.ListView;
/**
*用于在列表视图中处理多个选择的实用程序。包含
*类似于{@link AbsListView#CHOICE_MODE_MULTIPLE_model}的功能,但
*它与{@link ActionBarActivity}和向后兼容的操作一起工作
*酒吧。
*/
@TargetApi(构建版本代码蜂窝)
公共类MultiSelectionUtil{
公共静态控制器附件MultiSelectionController(
最终列表视图列表视图,最终操作活动活动,
最终多选模式(侦听器){
返回Controller.attach(listView、activity、listener);
}
@SuppressLint(“新API”)
公共静态类控制器实现ActionMode.Callback,
AdapterView.OnItemClickListener,
AdapterView.OnItemLongClickListener{
私有处理程序mHandler=新处理程序();
私人行动模式;
私有ListView mListView=null;
private ActionBarActivity MacActivity=null;
专用MultiChoiceModelListener mListener=null;
私有HashSet mTempIdsToCheckOnRestore;
私有HashSet-mItemsToCheck;
私有AdapterView.OnItemClickListener mOldItemClickListener;
专用控制器(){
}
公共静态控制器连接(ListView ListView,
ActionBarActivity活动,MultiChoiceModelListener侦听器){
控制器=新控制器();
controller.mListView=listView;
controller.mActivity=活动;
controller.mListener=侦听器;
setOnItemLongClickListener(控制器);
返回控制器;
}
私有void readInstanceState(Bundle savedInstanceState){
mTempIdsToCheckOnRestore=null;
如果(savedInstanceState!=null){
long[]checkedds=savedInstanceState
.getLongArray(getStateKey());
if(checkedds!=null&&checkedds.length>0){
mTempIdsToCheckOnRestore=new HashSet();
用于(长id:checkedIds){
mTempIdsToCheckOnRestore.add(id);
}
}
}
}
public void tryRestoreInstanceState(Bundle savedInstanceState){
readInstanceState(savedInstanceState);
tryRestoreInstanceState();
}
公共空间整理(){
if(mActionMode!=null){
mActionMode.finish();
}
}
public void tryRestoreInstanceState(){
如果(MTEMPIDTOCHECKONRESTORE==null
||mListView.getAdapter()=空){
返回;
}
布尔值=false;
Adapter=mListView.getAdapter();
对于(int pos=adapter.getCount()-1;pos>=0;pos--){
if(mTempIdsToCheckOnRestore.contains(adapter.getItemId(pos))){
idsFound=true;
if(mItemsToCheck==null){
mItemsToCheck=newhashset();
}
mItemsToCheck.添加(新的一对(位置、适配器
.getItemId(pos));
}
}
如果(idsFound){
//我们找到了一些已检查的ID。现在让我们还原
//多选
//国家。
MTEMPIDTOCHECKONRESTORE=null;//清除此临时字段
mActionMode=mActivity.startSupportActionMode(Controller.this);
}
}
公共布尔值saveInstanceState(Bundle expandle){
//TODO:通过持久化位置而不是
//身份证