2

我已經瀏覽了幾篇文章,但無法獲得複選框以確認點擊。我認爲我在那裏90%,但是在最後一個障礙中跌倒。Android:無法獲得複選框OnClickListener在ListFragment中工作

我有一個ListFragment,其中每個項目都有一個CheckBox和一個TextView。當用戶點擊TextView時,他們被帶到一個新的片段。但是當他們點擊複選框時,我希望在列表中直接勾選/取消勾選。

這裏是我的代碼,保持它,以便相關的ListView控件只類顯示,讓我知道如果你需要看別人。

我沒有按照這個指南,但不能真正理解爲什麼它不工作對我的代碼:http://www.mysamplecode.com/2012/07/android-listview-checkbox-example.html

TaskListFragment.java

package com.laytonlabs.android.todotoday; 

import java.util.ArrayList; 

import android.annotation.TargetApi; 
import android.app.Activity; 
import android.graphics.drawable.LayerDrawable; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v4.app.ListFragment; 
import android.util.Log; 
import android.view.ContextMenu; 
import android.view.ContextMenu.ContextMenuInfo; 
import android.view.ActionMode; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.View.OnTouchListener; 
import android.view.ViewGroup; 
import android.view.ViewTreeObserver; 
import android.view.ViewTreeObserver.OnGlobalLayoutListener; 
import android.widget.AbsListView.MultiChoiceModeListener; 
import android.widget.AdapterView; 
import android.widget.AdapterView.AdapterContextMenuInfo; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.CompoundButton.OnCheckedChangeListener; 
import android.widget.ArrayAdapter; 
import android.widget.CheckBox; 
import android.widget.CompoundButton; 
import android.widget.ListView; 
import android.widget.TextView; 

public class TaskListFragment extends ListFragment { 
    ArrayList<Task> mTasks; 
    private boolean mSubtitleVisible; 
    private Callbacks mCallbacks; 
    private static final String TAG = "TaskListFragment"; 
    private int touchPositionX; 

    public interface Callbacks { 
     void onTaskSelected(Task task); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     mCallbacks = (Callbacks)activity; 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mCallbacks = null; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
     getActivity().setTitle(R.string.crimes_title); 
     mTasks = TaskLab.get(getActivity()).getTasks(); 

     TaskAdapter adapter = new TaskAdapter(mTasks); 
     setListAdapter(adapter); 
     setRetainInstance(true); 
     mSubtitleVisible = false; 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     inflater.inflate(R.menu.fragment_crime_list, menu); 
     MenuItem showSubtitle = menu.findItem(R.id.menu_item_show_subtitle); 
     if (mSubtitleVisible && showSubtitle != null) { 
      showSubtitle.setTitle(R.string.hide_subtitle); 
     } 
    } 

    @TargetApi(11) 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.menu_item_new_crime: 
       Task task = new Task(); 
       TaskLab.get(getActivity()).addTaskToFirst(task); 
       ((TaskAdapter)getListAdapter()).notifyDataSetChanged(); 
       mCallbacks.onTaskSelected(task); 
       return true; 
      case R.id.menu_item_show_subtitle: 
       if (getActivity().getActionBar().getSubtitle() == null) { 
        getActivity().getActionBar().setSubtitle(R.string.subtitle); 
        mSubtitleVisible = true; 
        item.setTitle(R.string.hide_subtitle); 
       } else { 
        getActivity().getActionBar().setSubtitle(null); 
        mSubtitleVisible = false; 
        item.setTitle(R.string.show_subtitle); 
       } 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 

    @Override 
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 
     getActivity().getMenuInflater().inflate(R.menu.crime_list_item_context, menu); 
    } 

    @Override 
    public boolean onContextItemSelected(MenuItem item) { 
     AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); 
     int position = info.position; 
     TaskAdapter adapter = (TaskAdapter)getListAdapter(); 
     Task task = adapter.getItem(position); 

     switch (item.getItemId()) { 
     case R.id.menu_item_delete_crime: 
      TaskLab.get(getActivity()).deleteTask(task); 
      adapter.notifyDataSetChanged(); 
      return true; 
     } 
     return super.onContextItemSelected(item); 
    } 

    @TargetApi(11) 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { 
     View v = super.onCreateView(inflater, parent, savedInstanceState); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      if (mSubtitleVisible) { 
       getActivity().getActionBar().setSubtitle(R.string.subtitle); 
      } 
     }  

     ListView listView = (ListView)v.findViewById(android.R.id.list); 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
      //Use floating context menus on Froyo and Gingerbread 
      registerForContextMenu(listView); 
     } else { 
      //Use contextual action bar on Honeycomb and higher 
      listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); 
      listView.setMultiChoiceModeListener(new MultiChoiceModeListener() { 

       @Override 
       public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
        // TODO Auto-generated method stub 
        return false; 
       } 

       @Override 
       public void onDestroyActionMode(ActionMode mode) { 
        // TODO Auto-generated method stub 

       } 

       @Override 
       public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
        MenuInflater inflater = mode.getMenuInflater(); 
        inflater.inflate(R.menu.crime_list_item_context, menu); 
        return true; 
       } 

       @Override 
       public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 
        switch (item.getItemId()) { 
        case R.id.menu_item_delete_crime: 
         TaskAdapter adapter = (TaskAdapter)getListAdapter(); 
         TaskLab taskLab = TaskLab.get(getActivity()); 
         for (int i = adapter.getCount() - 1; i >= 0; i--) { 
          if (getListView().isItemChecked(i)) { 
           taskLab.deleteTask(adapter.getItem(i)); 
          } 
         } 
         mode.finish(); 
         adapter.notifyDataSetChanged(); 
         return true; 
        default: 
         return false; 
        } 
       } 

       @Override 
       public void onItemCheckedStateChanged(ActionMode mode, int position, 
         long id, boolean checked) { 
        // TODO Auto-generated method stub 

       } 
      }); 

     } 


     return v; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     ((TaskAdapter)getListAdapter()).notifyDataSetChanged(); 
    } 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     Task t = ((TaskAdapter)getListAdapter()).getItem(position); 
     mCallbacks.onTaskSelected(t); 
    } 

    private class TaskAdapter extends ArrayAdapter<Task> { 
     public TaskAdapter(ArrayList<Task> tasks) { 
      super(getActivity(), 0, tasks); 
     } 

     private class ViewHolder { 
      TextView titleTextView; 
      CheckBox completedCheckBox; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      ViewHolder holder = null; 
      //If we wern't given a view, inflate one 
      if (convertView == null) { 
       convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_task, null); 

       holder = new ViewHolder(); 
       holder.titleTextView = (TextView)convertView.findViewById(R.id.task_list_item_titleTextView); 
       holder.completedCheckBox = (CheckBox)convertView.findViewById(R.id.task_list_item_completedCheckBox); 
       convertView.setTag(holder); 

       holder.completedCheckBox.setOnClickListener(new OnClickListener() { 

        @Override 
        public void onClick(View v) { 
         CheckBox cb = (CheckBox) v; 
         Task task = (Task) cb.getTag(); 
         task.setCompleted(cb.isChecked()); 
         Log.d(TAG, "Clicked on checkbox for: " + task.getmTitle()); 
        } 
       }); 
      } else { 
       holder = (ViewHolder) convertView.getTag(); 
      } 

      //Configure the view for this Task 
      Task t = getItem(position); 
      holder.titleTextView.setText(t.getmTitle()); 
      holder.completedCheckBox.setChecked(t.isCompleted()); 
      holder.completedCheckBox.setTag(t); 

      return convertView; 
     } 
    } 

    public void updateUI() { 
     ((TaskAdapter)getListAdapter()).notifyDataSetChanged(); 
    } 

} 

list_item_task.xml

<?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="wrap_content" 
    android:orientation="horizontal" > 

    <CheckBox 
     android:id="@+id/task_list_item_completedCheckBox" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:enabled="false" 
     android:focusable="false" 
     android:focusableInTouchMode="false" 
     android:padding="4dp" /> 

    <TextView 
     android:id="@+id/task_list_item_titleTextView" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:textStyle="bold" 
     android:paddingLeft="4dp" 
     android:paddingRight="4dp" 
     android:text="Task title" /> 


</LinearLayout> 

在此先感謝!

+0

您需要在複選框上使用的偵聽器是OnCheckedChangeListener! –

+0

爲什麼您的複選框中的「enabled = false」? –

回答

2

點擊並未獲得直通的,因爲烏爾複選框

android:enabled="false" 

防止從射擊的onClickListener

刪除此行,然後重試。

另外,我勸你改變TextView的寬度爲wrap_content,和相當的複選框姿勢要正確。

+1

謝謝Marko!從我的XML中刪除以下行解決了問題。我離開了focusable和focusableInTouchMode,因爲我讀過這些需要標記爲false,否則listView滾動不響應? android:enabled =「false」 –

+0

這可能是正確的,點擊不會通過。我沒有使用這兩行,但我在行的主視圖中使用** android:descendantFocusability =「blocksDescendants」**來獲取點擊數(可能相當於將這兩行代碼放入CheckBox)。 – Marko

1

在你list_item_task.xml佈局文件,其中CheckBoxTextView的定義,您設置爲TextView

android:layout_width="match_parent" 

當它應該是作爲教程

android:layout_width="wrap_content" 

這是可能的太寬的文本正在攔截複選框中的點擊事件。

+0

謝謝。現在改變了這一點。 –