Maxim Zhukov
Maxim Zhukov

Reputation: 10140

ListView with custom ArrayAdapter setOnItemClickListener doesn't fire

I can't figure out why setOnItemClickListener doesn't work. I have ListView with custom ListItem layout,- and i'd like to start other activity when user click on row.

I saw lots of topic with this problem, but nothing helped.

Screen:

enter image description here

activity_main.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/notes_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/addNote">
    </ListView>

    <TextView
        android:id="@+id/empty_list_item"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/empty_notes"
        android:visibility="gone"
        android:gravity="center"
        android:layout_above="@+id/addNote"
    />

    <Button
        android:id="@+id/addNote"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/add_note"
        android:layout_alignParentBottom="true"
    />
</RelativeLayout>

list_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

    <!-- Note text-->
    <TextView
        android:id="@+id/noteText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#040404"
        android:typeface="sans"
        android:textSize="15dip"
        android:textStyle="bold" />

    <!-- Note createdAt -->
    <TextView
        android:id="@+id/noteCreatedAt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/noteText"
        android:textColor="#343434"
        android:textSize="10dip"
        android:layout_marginTop="1dip" />

    <!-- Note complete -->
    <Button
        android:id="@+id/btnCompleteNote"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="Complete" />
</RelativeLayout>

RNoteAdapter.java:

public class RNoteAdapter extends ArrayAdapter<RNote> {
    private Context context;
    private int resource;
    RNote[] data;
    private RNoteRepository noteRepository;

    public RNoteAdapter(Context context, int resource, RNote[] data) {
        super(context, resource, data);
        this.context = context;
        this.resource = resource;
        this.data = data;
        this.noteRepository = new RNoteRepository(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        RNoteHolder holder = null;

        if(row == null) {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(resource, parent, false);

            holder = new RNoteHolder();
            holder.noteText = (TextView)row.findViewById(R.id.noteText);
            holder.noteCreatedAt = (TextView)row.findViewById(R.id.noteCreatedAt);
            holder.btnCompleteNote = (Button)row.findViewById(R.id.btnCompleteNote);

            row.setTag(holder);
        } else {
            holder = (RNoteHolder)row.getTag();
        }

        final RNote note = data[position];

        if(note.IsCompleted) {
            holder.noteText.setPaintFlags(holder.noteText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
        }
        holder.noteText.setText(note.Text);

        DateFormat df = new SimpleDateFormat("dd.MM.yyyy в HH:mm");
        holder.noteCreatedAt.setText(df.format(note.CreatedAtUtc));

        holder.btnCompleteNote.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                note.IsCompleted = true;
                noteRepository.save(note);

                RNoteAdapter.this.notifyDataSetChanged();
            }
        });

        return row;
    }

    static class RNoteHolder {
        TextView noteText;
        TextView noteCreatedAt;
        Button btnCompleteNote;
    }
}

MainActivity.java

public class MainActivity extends ActionBarActivity {
    private RNoteRepository _noteRepository = new RNoteRepository(this);

    private Button addButton;
    private ListView notesList;

    RNoteAdapter adapter;

    private void init() {
        notesList = (ListView)findViewById(R.id.notes_list);
        addButton = (Button)findViewById(R.id.addNote);

        notesList.setEmptyView(findViewById(R.id.empty_list_item));
        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showEditNoteActivity(0);
            }
        });

        notesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                showEditNoteActivity(id);
            }
        });
    }

    private void updateData() {
        List<RNote> list = _noteRepository.getAll();
        RNote[] array = list.toArray(new RNote[list.size()]);

        adapter = new RNoteAdapter(this, R.layout.list_row, array);
        notesList.setAdapter(adapter);
    }

    private void showEditNoteActivity(long noteId) {
        Intent intent = new Intent(getApplicationContext(), EditNoteActivity.class);
        intent.putExtra("noteId", noteId);
        startActivityForResult(intent, 1);
    }

    private void showDialog(String text) {
        Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (data == null) {
            return;
        }
        String msg = data.getStringExtra("response");
        showDialog(msg);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
    }

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Upvotes: 0

Views: 762

Answers (2)

Blackbelt
Blackbelt

Reputation: 157487

add

android:descendantFocusability="blocksDescendants" 

to your ListView's row root.

The implementation of getItemId of ArrayAdapter returns position and not the id of your RNote, so you probably want to override it to make it return the correct information

Upvotes: 1

Mickey Tin
Mickey Tin

Reputation: 3543

set android:focusable="false" android:focusableInTouchMode="false" to all the clickable views (like button or editText) in your listView item

Upvotes: 1

Related Questions