8

ユーザーがクリックしたときにリストビュー項目の背景を変更したい。Honeycomb 設定ページのようなものです (ただし、設定だけを扱っているわけではないので、PreferenceActivity は使用していません) リストビュー メニューをクリックしてリニアリストビューの右側にレイアウトします (分割画面ビューの一種)。リストビューがフォーカスを失っていると推測しているため、state_pressed はもはや true ではありません。

   <item android:state_pressed="true">
     <shape  >
        <solid android:color="@color/blue1" />
     </shape>
   </item>

別のリストビュー項目が選択されるまで、そのリストビュー項目の色を維持するためのヒントはありますか? ありがとう!

編集:

setOnItemClickListener で背景を変更することができました

view.setBackgroundResource(R.color.red); 

一度に1つだけ選択する必要があるため、他のリスト項目をクリックすると、試しlv.invalidate()てみlv.getChildAt(0).invalidate()ましたが、どちらも機能せず、2番目はヌルポインター例外が発生します。色を戻すアイデアはありますか?

4

10 に答える 10

9

セルから指を離すと、押されたものとして登録されなくなります。あなたがしたいことは、ユーザーが選択したときに実際に個々の行の背景を変更することです. これは、onItemClickまたは onItemTouch を実装し、アダプターにフラグを立てて、新しい背景で行を再描画することを意味します。すでにカスタム リスト アダプターを使用している場合は、getView() メソッドでブール値に対するチェックを実装するだけです。また、どの行が「選択」され、どの行が選択されていないかを追跡する必要があります。

疑似コード:

   public View getView(int pos, View convertView, ViewGroup parent) {
      if(isChecked[pos]) //set background to checked color
   }
于 2011-04-15T20:40:32.053 に答える
4

この助けを願って、

1.- フォーカスされたアイテムの形状ファイルを作成します: \drawable\list_selector_focused.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

    <gradient android:angle="90" android:startColor="#f5c98c" android:endColor="#f7ddb8"/> 

</shape>

2.- 押されたアイテムの形状ファイルを作成します: \drawable\list_selector_pressed.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

    <gradient android:angle="90" android:startColor="#fb9d23" android:endColor="#ffc579" />

</shape>

3.- リスト セレクター ファイルを作成します: \drawable\list_selector.xml

    <selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" />
    <item android:drawable="@drawable/list_selector_focused" />

</selector>

4.- この属性をレイアウト ファイルの ListView に追加します。

 android:choiceMode="singleChoice"
 android:listSelector="@drawable/list_selector"

グラデーション形状の代わりに色を使用できます。

于 2013-03-17T22:02:20.307 に答える
3

これはsgarmanのアイデアの実装です。

    package com.mypackage;

import java.util.Vector;

import com.myapp.R;
import com.myapp.data.Address;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class AddressesListAdapter extends BaseAdapter{
    protected Context context;
    protected LayoutInflater mInflater;
    protected int itemResourceId;
    protected Vector<Address> contentItems = new Vector<Address>();
    protected Vector<Boolean> selectedStates;
    private static final String TAG = "myapp";

    public AddressesListAdapter(Context context, Vector<Address> contentItems) {
        this.context = context;
        this.contentItems = contentItems;
        mInflater = LayoutInflater.from(context);
        itemResourceId = R.layout.address_list_item;
        selectedStates = new Vector<Boolean>();
        //initial fill
        clearSelectedState();
    }

    @Override
    public int getCount() {
        return contentItems.size();
    }

    @Override
    public Object getItem(int position) {
        return contentItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(itemResourceId, null);

            holder = new ViewHolder();
            holder.addressName = (TextView) convertView.findViewById(R.id.addressName);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Address address = (Address) contentItems.get(position);
        holder.addressName.setText(address.getAddressName());
        holder.addressName.setOnClickListener(new SetFocusListener(position));

        //restore saved position from saving vector
        if (selectedStates.get(position)) holder.addressName.setBackgroundColor(Color.BLUE);
        else holder.addressName.setBackgroundColor(Color.TRANSPARENT);

        return convertView;
    }

    private void clearSelectedState () {
        selectedStates.clear();  
        for (int i = 0 ; i <= contentItems.size(); i++) {
            selectedStates.add(new Boolean(false));
        } 
    }

    private class SetFocusListener implements View.OnClickListener {
        private int position;

        public SetFocusListener(int position) {
            this.position = position;
        }

        @Override
        public void onClick(View v) {
            //clear selected state vector
            clearSelectedState();
            //set selected position
            selectedStates.set(position, new Boolean(true));
            //refresh adapter to redraw focus
            notifyDataSetChanged();
        }
    }

    static class ViewHolder {
          TextView addressName;
    }
}

getView() の反復ごとに新しいリスナーをセットアップするのはコストがかかりすぎるかもしれないという唯一の懸念

于 2011-09-23T09:17:05.813 に答える
3

この問題を解決するには、チェックされた Android の状態を使用するのが最適です。

誰かが android:background="?android:attr/activatedBackgroundIndicator" の使用について言及しました。

これは、Android ソース コードの frameworks/base/core/res/res/drawable にある activate_background_* リソースの 1 つを指しているだけです。たとえば、activated_background_holo_dark.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
  <item android:state_activated="true" android:drawable="@android:drawable/list_activated_holo" />
  <item android:drawable="@color/transparent" /> 
</selector>

したがって、基本的には、ユーザーがボタンを押したときと、ボタンがチェックされた状態 (つまり、永続的に選択された状態) にあるときを表すために、state_activated を使用する必要があります。アクティブ化は Honeycomb の後にのみ導入されたことに注意してください。古いデバイスをターゲットにしている場合は、state_checked に依存する必要があります (詳細はこちら)。

項目をチェック済みとして設定する場合は、 を呼び出す必要がありますlistView.setItemChecked(position, true)。ListViewのプロパティを適切な値に設定することをお勧めしandroid:choiceModeます (たとえば、一度に 1 つのみを選択する場合は を使用しますsingleChoice)。無効にする必要はありません。setItemChecked を呼び出すと、ビューを更新する再レイアウトがトリガーされます。

現在チェックされている項目を更新する必要があるため、ListView で項目の並べ替えを許可する場合も注意してください。安定した ID を使用する場合、これは自動的に処理されます。

この例を実際に確認するには、トレーニング シリーズhttp://developer.android.com/training/implementing-navigation/nav-drawer.htmlにある NavigationDrawer サンプル コードを確認してください。

于 2013-08-31T14:07:22.713 に答える
2

デフォルトでは、タッチ インターフェースを使用している場合、'Selected' は 'Clicked' と同じではありません。これは、私が Android 開発を始めたときに、頭痛の種になる原因です。

タッチでナビゲートするユーザーとスクロールホイール/トラックボールを使用するユーザーの両方をサポートするには、 setSelectionを使用し、 AdapterView.OnItemSelectedListener実装 ( setOnItemSelectedListener で設定) で操作を行うことができます。

もう 1 つの落とし穴は、最後のイベントがタッチ イベントの場合、setSelectionが項目を強調表示しないことです。

リスト アイテムのカスタム ビューを作成し、そこで強調表示を処理することをお勧めします。

お役に立てれば、

フィル・レロ

于 2011-04-15T21:33:46.940 に答える
0

わかりましたので、「これは sgarman のアイデアの実装です:」というところから上記の解決策を試しました。これは、SetFocusListener が OnTouchListner である場合にのみ機能します。それ以外の場合、onClick メソッドはクリックを消費します。ハイライトされたアイテムを実際に表示するリストを取得するには、このソリューションをリスト アイテムの OnItemClick リスナーと組み合わせる必要がありました。

于 2014-10-18T17:26:34.907 に答える
0

android:state_activated="true"の代わりに使用 しましたstate_selected。それは魅力のように機能します!

于 2015-01-20T12:53:28.387 に答える
0

アクティビティ全体を通して listView を維持するmListView.isItemChecked(position)と、getView()メソッドで a を実行できます。そして、結果に応じて背景色を設定します。

于 2015-02-27T20:21:41.710 に答える
-2

試す

    android:background="?android:attr/activatedBackgroundIndicator"

;)

于 2013-03-30T19:09:31.740 に答える
-2

試しましたandroid:state_selected="true"か?

于 2011-04-15T20:39:26.170 に答える