Frage

Ich versuche neu zu erstellen, was Google mit der ListView in der Google Mail -App gemacht hat. Insbesondere möchte ich, dass jedes Listenelement ein Kontrollkästchen und zwei Textviews (eine übereinander) enthalten. Ich brauche Hörer, wenn das Kontrollkästchen aktiviert ist (oder geklickt) und wenn sonst irgendwo im Listenelement geklickt wird. Zuletzt möchte ich, dass die ActionBar widerspiegelt, dass Elemente ausgewählt werden, und Optionen wie alle auswählen, keine auswählen usw. (siehe Dieser Screenshot).

enter image description here

Bisher ist hier das Layout, das ich mir ausgedacht habe.

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

    <CheckBox android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|center_horizontal" />

    <LinearLayout android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="6dp"
        android:focusable="true"
        android:clickable="true" >

        <TextView android:id="@+id/titleTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="16sp" />

        <TextView android:id="@+id/dateTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="12sp" />

    </LinearLayout>

</LinearLayout>

Dies zeigt alles richtig, aber ich brauche Hinweise darauf, wie die Zuhörer für die beiden Ansichten eingerichtet werden können (@+id/Kontrollkästchen und @+id/linearlayout1). Ich habe mir das angesehen LIST16 API -Demo, Aber sie verwenden das Layout von Simple_List_item_activated_1 und ich bin mir nicht sicher, wie das XML dafür aussieht. Wie ihr Code schon sagt, habe ich a erstellt ModEcallback Klasse, die implementiert ListView.multichoicemodelistener Und ich habe den Auswahlmodus von ListView auf choice_mode_multiple_modal festgelegt, aber ich weiß nicht, wie das Kontrollkästchen in meinem Layout damit funktioniert.

Hat jemand das ListView -Verhalten der Google Mail -App erfolgreich kopiert? Ich habe ziemlich viel gesucht und konnte mir nichts einfallen lassen (obwohl einige andere ähnliche Fragen stellten, wie dieser - Die meisten Antworten verweisen einfach auf dieselbe API -Demo).

Außerdem lade ich für den Kontext Daten aus einer SQLite -Datenbank in die Liste und habe meinen eigenen Cursoradapter erstellt (was gut funktioniert). Ich habe das Gefühl, dass ich Hörer in dieser Klasse in den Methoden NewView () und BindView () einrichten muss, aber alles, was ich ausprobiert habe, hat nicht funktioniert.

Irgendwelche Ideen?

War es hilfreich?

Lösung

Der Modus in der Abbildung wird als Action -Modus bezeichnet. Wenn Sie Ihre benutzerdefinierte Zeilenansicht und Ihren benutzerdefinierten Adapter verwenden, müssen Sie nicht für den Aktionsmodus von Choice_Mode_Multiple_Modal starten. Ich habe es einmal ausprobiert und habe versagt, und ich vermute, dass es für eingebaute Adapter verwendet wird.

Um den Action -Modus selbst in Ihrem Code selbst aufzurufen, rufen Sie die StartActionMode in einer beliebigen Listener -Methode Ihrer Ansicht auf. Anschließend übergeben Sie den Moduscallback als Parameter in ihn und machen die Operation, die Sie in der MODECALLBACK -Klasse ausführen möchten.

Ich glaube nicht, dass dies auf Android vor 3.0 funktionieren würde.

Hier ist ein kurzes Beispiel. Ich habe eine erweiterbare Listenaktivität und möchte das Menü Aktionsmodus anrufen, wenn Benutzer das Kontrollkästchen überprüfen/deaktivieren. Hier finden Sie meine GetChildView -Methode in meiner benutzerdefinierten Adapterklasse:

public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {

        if (convertView == null) {
            LayoutInflater inflater =  (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.childrow, null);
        }
        CheckBox cb = (CheckBox)convertView.findViewById(R.id.row_check);
        cb.setChecked(false);   // Initialize
        cb.setTag(groupPosition + "," + childPosition);
        cb.setFocusable(false); // To make the whole row selectable
        cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                String tag = (String)buttonView.getTag();
                String[] pos = tag.split(",");
                if (isChecked) {
                    if (mActionMode == null) mActionMode = startActionMode(mMultipleCallback);                      
                }
                else {
                    if (mActionMode != null) {  // Only operate when mActionMode is available

                        mActionMode.finish();
                        mActionMode = null;
                    }
                }
            }
        });

        TextView tvTop = (TextView)convertView.findViewById(R.id.row_text_top);
        TextView tvBottom = (TextView)convertView.findViewById(R.id.row_text_bottom);
        tvTop.setText(mChildren.get(groupPosition).get(childPosition));
        tvBottom.setText(mChildrenSize.get(groupPosition).get(childPosition));
        return convertView;
    }

Andere Tipps

Dies funktioniert in SDK 7 (Android 2.1) und höher. (zusammen mit SherlockactionBar)

Totaly Mimic Google Mail Listbox Experience.

Ich überschreibe OnTouchEnvent. Drücken Sie also auf der linken Ecke und aktivieren den Auswahlmodus. Mutch besser als versuchen, auf die winzige Cheazkbox zu klicken.

Ich habe PerformItemclick überschrieben, sodass das Drücken nicht links als reguläre Presseaktion wirkt.

Ich habe setItemChecked überragend, damit es nach Bedarf mactionMode aktualisiert wird.

public class SelectListView extends ListView {

    private SherlockFragmentActivity mActivity;
    ActionMode mActionMode;

      public SelectListView(Context context) {
    this( context, null, 0); 
}

public SelectListView(Context context, AttributeSet attrs) {   
    this( context, attrs, 0); 
}   


public SelectListView(Context context, AttributeSet attrs, int defStyle) {
    super( context, attrs, defStyle ); 
    setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    mActivity = (SherlockFragmentActivity) context;
}

    @Override
    public boolean performItemClick(View view, int position, long id) {
        OnItemClickListener mOnItemClickListener = getOnItemClickListener();
        if (mOnItemClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            if (view != null)
                view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
            mOnItemClickListener.onItemClick(this, view, position, id);
            return true;
        }
        return false;
    }

    boolean mSelectionMode = false;
    int mStartPosition;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        final int action = ev.getAction();
        final int x = (int) ev.getX();
        final int y = (int) ev.getY();

        if (action == MotionEvent.ACTION_DOWN && x < getWidth() / 7) {
            mSelectionMode = true;
            mStartPosition = pointToPosition(x, y);
        }
        if (!mSelectionMode)
            return super.onTouchEvent(ev);
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_MOVE:
            if (pointToPosition(x, y) != mStartPosition)
                mSelectionMode = false;
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
        default:
            mSelectionMode = false;
            int mItemPosition = pointToPosition(x, y);
            if (mStartPosition != ListView.INVALID_POSITION)
                setItemChecked(mItemPosition, !isItemChecked(mItemPosition));
        }

        return true;
    }

    @Override
    public void setItemChecked(int position, boolean value) {
        super.setItemChecked(position, value);
        // boolean r = getAdapter().hasStableIds();
        int checkedCount = getCheckItemIds().length;

        if (checkedCount == 0) {
            if (mActionMode != null)
                mActionMode.finish();
            return;
        }
        if (mActionMode == null)
            mActionMode = mActivity.startActionMode(new ModeCallback());

        mActionMode.setTitle(checkedCount + " selected");

    }

    class ModeCallback implements ActionMode.Callback {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {

            menu.add(getResources().getString(R.string.aBar_remove)).setIcon(R.drawable.ic_action_trash)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            Toast.makeText(mActivity, "Delted  items", Toast.LENGTH_SHORT).show();
            mode.finish();
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
            clearChecked();
        }

    }

    public void clearChecked() {
        SparseBooleanArray CItem = getCheckedItemPositions();
        for (int i = 0; i < CItem.size(); i++)
            if (CItem.valueAt(i))
                super.setItemChecked(CItem.keyAt(i), false);
    }

}

Sie können jedes Listbox -Adapter verwenden, den Sie benötigen.

Wenn Sie ein Kontrollkästchen auf Ihrer LISTE_ITEM_LAYOUT haben, müssen Sie Ihren Adapter wie folgt ausdehnen:

ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(this, R.layout.simple_list_item_multiple_choice,
            R.id.text1, Cheeses.sCheeseStrings) {

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = super.getView(position, convertView, parent);
            CheckBox checkBox = (CheckBox) v.findViewById(R.id.CheckBox);
            checkBox.setChecked(((ListView)parent).isItemChecked(position));
            return v;
        }

    };

Vergessen Sie nicht, Android zu verwenden: Hintergrund = "? Attr/ActivatedBackgroundindicator" auf Ihrer LISTE_ITEM_LAYOUT.xml

Zusätzlich verwenden Sie die Antwort von ToCNBUFF410. Verwenden Sie den folgenden Code, um die Anzahl der geprüften Elemente zu aktualisieren

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
    ++checkBoxCount;
 } else {
    --checkBoxCount;
 }
...

if (mActionMode != null) {
    mActionMode.setSubtitle(checkBoxCount + " item(s) selected.");
}

Ich kann bestätigen, dass der folgende Code nicht auf Kontrollkästchen benutzerdefinierter ListViews funktioniert. Lange Presse würde jedoch immer noch funktionieren:

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new ModeCallback());

Das Auswählen des Kontrollkästchens im benutzerdefinierten ListView würde ActionMode nicht auslösen. Nur eingebaute ListViews, z. B. Erweiterungslistenaktivität, würde dies automatisch tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top