0

さて、これは理解するのが難しい問題かもしれません。

私が実際に望んでいたこと :通話ログから個別の発信者の入力済みリストを取得するには、ユーザーが必要に応じて選択し、ボタンをタップしてブラックリストに登録します。

したがって、私が望んでいたのは次のとおりであると結論付けました

結論私が欲しかったもの:ヘッダーボタンとアイテムのリストを備えたアクティビティを持つこと。アイテムのリストから、ユーザーは任意の数のアイテムを選択し (チェックボックスを使用してこれを実装しました。後でどのように実行したかを示します)、ヘッダー ボタンを選択してアクションを実行できます。

私がやったこと:活動のレイアウト:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
    <LinearLayout android:id="@+id/add_btn_layout" android:layout_width="match_parent" android:layout_height="50dp" android:padding="2dp" >
        <Button android:id="@+id/btn_blacklist_sender" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="21dp" >
        </Button>
    </LinearLayout>
    <ListView android:id="@+id/list_chose_to_blacklist" android:layout_width="wrap_content" android:layout_height="wrap_content" >
    </ListView>
</LinearLayout>

行のレイアウト:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:padding="2dp" >
<CheckBox android:id="@+id/isDelete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="43dp" android:paddingRight="3dp" />
</LinearLayout>

アクティビティでは:

public class CallerChooseToBlacklistActivity extends Activity {

Button btnBlacklistCaller;
ListView listCallers;
HashSet<String> toBlacklistNumbers = new HashSet<String>();
String caller = "Sender";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chose_to_blacklist);

    btnBlacklistCaller = (Button) findViewById(R.id.btn_blacklist_sender);
    btnBlacklistCaller.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            BlacklistNumberHelper helper = new BlacklistNumberHelper(
                    getApplicationContext());
            for (String number : toBlacklistNumbers) {
                helper.insert(number, DbHelper.TABLE_CALL_BLACKLIST,
                        DbHelper.C_CALL_BLACKLIST_NO);
            }
            helper.close();
            onResume();
        }
    });
    btnBlacklistCaller.setText(getString(R.string.btn_blacklist_caller));

    listCallers = (ListView) findViewById(R.id.list_chose_to_blacklist);
}

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

    String[] projection = new String[] { CallLog.Calls._ID,
            CallLog.Calls.NUMBER };
    Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI,
            projection, null, null, null);

    for (int idx = 0; idx < cursor.getColumnCount(); idx++) {
        Log.d(MainActivity.TAG, idx + ":" + cursor.getColumnName(idx));
    }

    HashSet<String> distinctCallers = new HashSet<String>();
    ArrayList<String> allreadyBlacklisted = (new BlacklistNumberHelper(
            getApplicationContext())).getAllNumbers(
            DbHelper.TABLE_CALL_BLACKLIST, DbHelper.C_CALL_BLACKLIST_NO);
    if (cursor.moveToFirst()) {
        for (int i = 0; i < cursor.getCount(); i++) {
            try {
                String address = cursor.getString(
                        cursor.getColumnIndexOrThrow("number")).toString();
                boolean isPresent = false;
                for (String no : allreadyBlacklisted)
                    if (no.equalsIgnoreCase(address)) {
                        isPresent = true;
                        break;
                    }
                if (!isPresent)
                    distinctCallers.add(address);
                cursor.moveToNext();
            } catch (IllegalArgumentException e) {
            }
        }
    }

    ArrayList<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();

    for (String address : distinctCallers) {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put(caller, address);
        fillMaps.add(map);
    }

    String[] from = { caller };
    int[] to = { R.id.isDelete };
    SimpleAdapter cursorAdapter = new SimpleAdapter(this, fillMaps,
            R.layout.row_blacklist, from, to);
    cursorAdapter.setViewBinder(VIEW_BINDER);
    listCallers.setAdapter(cursorAdapter);
}

// custom binder to bind columns customally
final ViewBinder VIEW_BINDER = new ViewBinder() {
    public boolean setViewValue(View view, Object arg1, String arg2) {
        if (view.getId() == R.id.isDelete) {
            CheckBox cb = (CheckBox) view;
            cb.setText(arg2);
            cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                public void onCheckedChanged(CompoundButton buttonView,
                        boolean isChecked) {
                    String text = buttonView.getText().toString();
                    if (isChecked)
                        toBlacklistNumbers.add(text);
                    else if (toBlacklistNumbers.contains(text))
                        toBlacklistNumbers.remove(text);
                }
            });
            return true;
        } else {
            return false;
        }
    }

};
}

問題は何ですか:アイテムを選択して下にスクロールし、上にスクロールして戻ってくると、選択したアイテムのチェックが変更されます。ハッシュセットを見ると、toBlacklistNumbers最初に選択した番号しかありません。つまり、ヘッダー ボタンをタップすると、ブラックリストに登録されます。ハッシュセットから削除するには、最初に選択してから選択を解除する必要があります。しかし、これは私が望むものではありません。

リストを下にスクロールしたときにアイテムが選択解除されないようにします。Android 2.2とAndroid 4.1で確認したので、これは明らかにAndroidバージョンの問題ではありません

更新:選択したアイテムが変更されるということは、選択したアイテムが選択されなくなり、代わりにその上または下のアイテムが選択されることを意味しました。また、下にスクロールすると、下のリストの多くの項目も自動的に選択されます

4

1 に答える 1

1

CheckBoxのデータに基づいてのステータスを設定していませんtoBlacklistNumbers:

@Override
public boolean setViewValue(View view, Object arg1, String arg2) {
            if (view.getId() == R.id.isDelete) {
                CheckBox cb = (CheckBox) view;
                cb.setText(arg2);
                String data = (String) arg1;
                if (toBlacklistNumbers.contains(data)) {
                    cb.setChecked(true);
                } else {
                    cb.setChecked(false);
                }               
                cb.setOnCheckedChangeListener(mListener);
                return true;
            } else {
                return false;
            }
        }

wheremListenerは単一でOnCheckedChangeListenerあるため、ユーザーがスクロールするたびに作成する必要はありません。

private OnCheckedChangeListener mListener = new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            String text = buttonView.getText().toString();
            if (isChecked)
                toBlacklistNumbers.add(text);
            else if (toBlacklistNumbers.contains(text))
                toBlacklistNumbers.remove(text);
        }
    };

また、onResumeメソッドを自分で呼び出さないでください。これは、システムによってのみ呼び出されるライフサイクル メソッドです。

于 2012-10-25T11:37:25.840 に答える