0

My issue is, that i can't solve to change the apperance of my TextView at the correct position, when I toggle a checkbox, which is part of a ListView. The goal is to STRIKE_THRU the text and (as the next step) give back the changed status to database, when CheckBox is checked.

Independent which Checkbox of the list is clicked, everytime the first row is changed. How can I change code, to get the STRIKE_THRU text on the affected row? (I just started on Android)

Important is that I can still start another acitivity to sho details, when clicking on TextView.

Code for ListActivity

import android.app.ListActivity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.TextView;

public class TaskListActivity extends ListActivity implements OnCheckedChangeListener {

private Cursor dbCursor;
private TaskAdapter listAdapter;
String lUID;
CheckBox cb;
TextView textview1, textview2;
ContentValues values;
ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    lUID = intent.getStringExtra("List");
    Uri uri = Uri.withAppendedPath(Provider.CONTENT_URI_TASKSLIST, lUID);
    dbCursor = getContentResolver().query(uri,
            null, null, null, OpenHandler.TASKS_NAME + " DESC");

startManagingCursor(dbCursor);

listAdapter = new TaskAdapter(this, dbCursor);
setListAdapter(listAdapter);

lv=getListView();
lv.setItemsCanFocus(true);
lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // TODO
        Log.d("Position", "Test: " + position);
        //works fine    
        }
    });



    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int pos = (Integer)buttonView.getTag();
        //Gives the correct position of the clicked CheckBox
        System.out.println("Pos ["+pos+"]");

        if (pos != ListView.INVALID_POSITION) {

         CheckBox cb = (CheckBox) buttonView.findViewById(R.id.checkbox);
         textview1 = (TextView) findViewById(R.id.text1);
         textview2 = (TextView) findViewById(R.id.text2);

         if(cb.isChecked()==true){
            cb.setChecked(true);
            textview1.setTextColor(Color.GRAY);
            textview1.setPaintFlags(textview1.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
            textview2.setTextColor(Color.GRAY);
            textview2.setPaintFlags(textview2.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
        }
         }

   }
}

Code for Adapter

import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CursorAdapter;
import android.widget.TextView;



public class TaskAdapter extends CursorAdapter {


private LayoutInflater inflator;
private int ciTasksList, ciTasksName;
private Context context;
private Cursor c;
private CheckBox cb;


public TaskAdapter(Context context, Cursor c) {
    super(context, c);
    this.c = c;
        this.context = context;

    inflator = LayoutInflater.from(context);
    ciTasksName = c.getColumnIndex(OpenHandler.TASKS_NAME);
    ciTasksList = c.getColumnIndex(OpenHandler.TASKS_LIST);
} 

@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {

    if (!c.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position " + position);
    }
    View v;
    if (convertView == null) {
        v = newView(context, c, viewGroup);
    } else {
        v = convertView;
    }
    bindView(v, context, c);
    cb = (CheckBox) v.findViewById(R.id.checkbox);
    cb.setTag(position);
    cb.setOnCheckedChangeListener((TaskListActivity) context);

    return v;


}


@Override
public void bindView(View view, Context context, Cursor cursor) {
    TextView textview1 = (TextView) view.findViewById(R.id.text1);
    TextView textview2 = (TextView) view.findViewById(R.id.text2);
    String TasksName = cursor.getString(ciTasksName);
    String TasksList = cursor.getString(ciTasksList);

    textview1.setText(TasksName);
    textview2.setText("ID " + TasksList);

} 

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return inflator.inflate(R.layout.check_text_text, null);
}
}

and the code for Layout:

<CheckBox android:id="@+id/checkbox"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginRight="6dip"
    android:layout_width="wrap_content"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:layout_height="fill_parent"/>         

<TextView android:id="@+id/text1"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:layout_marginTop="4dip"
    android:layout_toRightOf="@id/checkbox"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

<TextView android:id="@+id/text2"
    android:textAppearance="?android:attr/textAppearanceSmall"  
    android:layout_below="@id/text1"
    android:layout_alignLeft="@id/text1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

</RelativeLayout>

EDIT Instead of

cb = (CheckBox) v.findViewById(R.id.checkbox);
cb.setTag(position);
cb.setOnCheckedChangeListener((TaskListActivity) context);

in Adapter class I changed to (many thanks to erdomester):

 cb = (CheckBox) v.findViewById(R.id.checkbox);
 cb.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
       cb = (CheckBox) view.findViewById(R.id.checkbox);
       textview1 = (TextView) v.findViewById(R.id.text1);
       textview2 = (TextView) v.findViewById(R.id.text2);

       if(cb.isChecked()==true){
         cb.setChecked(true);
         textview1.setTextColor(Color.GRAY);
         // [...]
       }
    }
 });

taken the code for "onClick" from the former "onCheckedChanged" of the activity.

Edit2

It is still not the expected result. What I didn't get on the first test is, that it now only works on the last row. (Same result when deleting cb = (CheckBox) view.findViewById(R.id.checkbox); in onClick). Any ideas?

Joerch80
  • 1
  • 3
  • In onCheckedChanged: You are referencing the checkbox in the buttonView but you are referencing the textviews as they were in the layout of the activity. – erdomester Mar 15 '14 at 13:41
  • When i write "textview1 = (TextView) buttonView.findViewById(R.id.text1);" instead of "textview1 = (TextView) findViewById(R.id.text1);", I get a NullPonterException on "textview1.setTextColor(Color.GRAY);" – Joerch80 Mar 15 '14 at 13:55

1 Answers1

0

How about dropping the onCheckedChangeListener() and using setOnClickListener() inside the getView() function? (Remember to remove it from the class initiation line as well).

checkBox.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View arg0) {
        final boolean isChecked = checkBox.isChecked();
        // Do something here.
    }
});
erdomester
  • 11,789
  • 32
  • 132
  • 234