Android-无法获取列表视图项目

时间:2011-12-11 10:46:41

标签: java android listview

我有一个带有两个textview的自定义列表视图。如果我使用模拟器d-pad,一切正常,行被选中,但如果我点击模拟器上的项目(或尝试在手机上选择),则不会选择任何内容。

addresslist.xml:
    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:orientation="horizontal" android:paddingBottom="6dip"
    android:paddingTop="4dip">

    <TextView android:id="@+id/DENUMIRE_CELL"
        android:layout_width="50dp" android:layout_height="wrap_content"
        android:layout_weight="1.03" />

    <TextView android:id="@+id/ADRESA_CELL" android:layout_width="50dp"
        android:layout_height="wrap_content" android:layout_weight="0.84" />
</LinearLayout>
clienti.xml:

    <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical">

    <TableRow android:id="@+id/tableRow1" android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <LinearLayout android:orientation="horizontal"
            android:focusable="true" android:focusableInTouchMode="true">
            <EditText android:id="@+id/editTextCauta"
                android:layout_width="100dp" android:layout_height="wrap_content"
                android:layout_weight="0.04" />

            <Button android:id="@+id/buttonCauta" android:layout_width="70dp"
                android:layout_height="wrap_content" android:text="Cauta" />
        </LinearLayout>

    </TableRow>
    <TableRow android:id="@+id/tableRowHeader"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:background="#000000">

        <LinearLayout android:orientation="horizontal">
            <TextView android:id="@+id/textView1" android:layout_width="159dp"
                android:layout_height="wrap_content" android:text="Denumire"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#BBBBBB" android:textSize="15sp" />
            <TextView android:id="@+id/textView2" android:layout_width="159dp"
                android:layout_height="wrap_content" android:text="Adresa"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#BBBBBB" android:textSize="15sp" />

        </LinearLayout>

    </TableRow>
    <TableRow android:id="@+id/tableRow2" android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:baselineAligned="false">


        <ListView android:id="@+id/adresslist" android:layout_width="wrap_content"
            android:choiceMode="singleChoice" android:layout_height="wrap_content"
            android:scrollbars="horizontal|vertical" />

    </TableRow>


</TableLayout>

代码:

    public void adresalistBind()
        {
            listview = (ListView) findViewById(R.id.adresslist);

            ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
            ArrayList<ClientClass> clientlist=new ArrayList<ClientClass>();

            ClientClass.setClientContextForDB(this);

            clientlist=ClientClass.ClientiGet();

            listaAll=clientlist;


            HashMap<String, String> map;

            for(int i=0;i<clientlist.size();i++)
            {
                map = new HashMap<String, String>();
                map.put("denumire", clientlist.get(i).getDenumire());
                map.put("adresa", clientlist.get(i).getAdresa());
                map.put("clientid", String.valueOf(clientlist.get(i).getClientID()));
                mylist.add(map);
            }

            SimpleAdapter mAdapter = new SimpleAdapter(this, mylist, R.layout.addresslist,
                        new String[] {"denumire", "adresa"}, new int[] {R.id.DENUMIRE_CELL, R.id.ADRESA_CELL});
            listview.setAdapter(mAdapter);
            listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            listview.setSelection(1);
            listview.setOnItemSelectedListener(new OnItemSelectedListener() 
            {
                public void onItemSelected(AdapterView<?> adaptview, View clickedview, int position,
                        long id) 
                {
                    //adaptview.setSelected(true);
                    listview.setSelection(position);
                }

                public void onNothingSelected(AdapterView<?> arg0) 
                {
                }

            });

            listview.setOnItemClickListener(new OnItemClickListener() 
            {
                public void onItemClick(AdapterView<?> adaptview, View arg1,
                        int position, long arg3) 
                {
                    //adaptview.setSelected(true);
                   // View rowview = (View) adaptview.getChildAt(position);
                   // rowview.setSelected(true);
                    listview.setSelection(position);

                    //Toast.makeText(ClientiForm.this,  (String) listview.getItemAtPosition(position).toString(), 10000).show();
                }
            });

            listview.setOnItemLongClickListener(new OnItemLongClickListener() 
            {

                public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                        int position, long arg3) 
                {
                    listview.setSelection(position);
                    openOptionsMenu();

                    Toast.makeText(ClientiForm.this,  (String) listview.getItemAtPosition(position).toString(), 10000).show();
                    return false;
                }
            });
        }

2 个答案:

答案 0 :(得分:6)

为了使项目“可检查”,项目的顶视图应实现Checkable界面。只有在这种情况下,您才会在ListView内获得“已检查”/“未选中”状态。

请注意,“可选择”和“可检查”项目具有不同的含义。在您的情况下,您的意思是“可检查”项目。不是“可选择的”。您需要“检查”您的商品,但ListView确保在CHOICE_MODE_SINGLE中一次最多检查一件商品。 “selected”项目是当前活动的项目(这主要用于可访问性需求)。

您只需在列表项的布局中用LinearLayout视图替换CheckBox即可验证我的说法。 ListView应自动开始处理“已检查”状态。


如果您想使用LinearLayout并且仍然能够支持“已选中”/“未选中”状态,则需要实现扩展LinearLayout并实现Checkable接口的自定义布局。

以下是我的此实现版本:

public class CheckableLinearLayout extends LinearLayout implements Checkable {

    private boolean mChecked;

    private static final int[] CHECKED_STATE_SET = {
        android.R.attr.state_checked
    };

    public CheckableLinearLayout(Context context) {
        this(context, null);
        init();
    }

    public CheckableLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {      
        setClickable(true);
    }

    /**********************/
    /**   Handle clicks  **/
    /**********************/

    @Override
    public boolean performClick() {
        toggle();
        return super.performClick();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return onTouchEvent(ev);
    }

    /**************************/
    /**      Checkable       **/
    /**************************/

    public void toggle() {
        setChecked(!mChecked);
    }

    public boolean isChecked() {
        return mChecked;
    }

    public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState();
            setCheckedRecursive(this, checked);
        }
    }  

    private void setCheckedRecursive(ViewGroup parent, boolean checked) {
        int count = parent.getChildCount();
        for(int i = 0; i < count; i++ ) { 
            View v = parent.getChildAt(i);
            if(v instanceof Checkable) {
                ((Checkable) v).setChecked(checked);
            }

            if(v instanceof ViewGroup) {
                setCheckedRecursive((ViewGroup)v, checked);
            }
        }
    }

    /**************************/
    /**   Drawable States    **/
    /**************************/

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
        }
        return drawableState;
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();

        Drawable drawable = getBackground();
        if (drawable != null) {
            int[] myDrawableState = getDrawableState();
            drawable.setState(myDrawableState);
            invalidate();
        }
    }

    /**************************/
    /**   State persistency  **/
    /**************************/

    static class SavedState extends BaseSavedState {
        boolean checked;

        SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            checked = (Boolean)in.readValue(null);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeValue(checked);
        }

        @Override
        public String toString() {
            return "CheckableLinearLayout.SavedState{"
                    + Integer.toHexString(System.identityHashCode(this))
                    + " checked=" + checked + "}";
        }

        public static final Parcelable.Creator<SavedState> CREATOR
                = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

    @Override
    public Parcelable onSaveInstanceState() {
        // Force our ancestor class to save its state
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState);

        ss.checked = isChecked();
        return ss;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;

        super.onRestoreInstanceState(ss.getSuperState());
        setChecked(ss.checked);
        requestLayout();
    }
}

您的项目布局应如下所示:

<com.your.pkg.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:background="@drawable/checkable_item">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Large Text"
            android:textAppearance="?android:attr/textAppearanceLarge" />
</com.your.pkg.CheckableLinearLayout>

请注意“drawable / checakble_item”。它应该处理不同的状态。在我的例子中,它看起来像:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:state_pressed="true" android:drawable="@drawable/item_pressed" />
    <item android:state_checked="true" android:drawable="@drawable/item_checked"/>
    <item android:drawable="@drawable/item_unchecked" />

</selector>

drawable/item_presseddrawable/item_checkeddrawable/item_unchecked是我的自定义绘图。

最后一个注释:在Adapter getView()中,您必须致电view.setClickable(false);,以便ListView而不是{{1}处理可检查状态}}

答案 1 :(得分:0)

您可以在this link找到解决方案。您必须以编程方式更改布局的外观。

相关问题