从ListFragment访问SimpleCursorAdapter中的视图

时间:2014-09-15 18:32:52

标签: android android-adapter android-listfragment

我有ListFragment SimpleCursorAdapter,并希望为longClickListener中的每个items设置list,即TextViews之一{每个项目{1}}。 因此,我需要访问TextView以在该视图上调用setOnLongClickListener

ListFragment(我总是从findViewById获取null,但想使用setOnLongClickListener):

 public class OverviewFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {

    ...

    @Override
    public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle b ) {
        View fragView = inflater.inflate( R.layout.overview_fragment, container, false );
        return fragView;
    }

    @Override
    public void onActivityCreated( Bundle state ) {
        super.onActivityCreated (state );
        getLoaderManager().initLoader( LOADER_ID_READ_OVERVIEW, null, this );
        adapter = new SimpleCursorAdapter( getActivity(), R.layout.overview_row, null, overviewDbColumns, overviewTargetViewIds, 0 );
        setListAdapter( adapter );
        TextView tv = (TextView) getListView().findViewById( R.id.overviewFooName );
        if ( tv == null ) { //is always null!!!
            Log.e( TAG, "OverviewFragment->onActivityCreated: tv == null" );
        } else {
            tv.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    if ( mActionMode != null ) { 
                        return false;
                    }
                    mActionMode = getActivity().startActionMode(mActionModeCallback);
                    view.setSelected(true);
                    return true;
                }
            });
        }
    }

overview_fragment.xml:

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include layout="@android:layout/list_content" />
<ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:choiceMode="singleChoice" >
</ListView>
<TextView
    android:id="@android:id/empty"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/no_foo_in_list" 
/>

和overview_row.xml(由SimpleCursorAdapter使用):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
    android:id="@+id/overviewFooName"
    android:clickable="true"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent" />
<TextView
    android:id="@+id/overviewFooType"
    android:layout_width="wrap_content"
    android:layout_height="26dp" />

<TextView
    android:id="@+id/overviewFooDbIndex"
    android:layout_width="wrap_content"
    android:layout_height="26dp" />

我对android如何使用视图层次结构的想法似乎是错误的。 我的想法是一棵树,我可以从任何其他更接近根的节点访问每个节点 - 只要我知道它的ID。 这是对的吗?

如果这个想法错了,正如我所料 - 我如何访问TextView(或整个项目)? 我在哪里放置mActionModeCallback的代码?

2 个答案:

答案 0 :(得分:0)

我自己没有尝试过这个问题,我认为这里的问题是你给findViewById(R.id.overViewFooName)的ID是不明确的:由于每个列表项包含一个带有此ID的TextView,框架应如何决定,哪个在findViewById中返回?

所以,我认为你有两个选择:

  1. 只使用ListView的内置功能,即setOnItemLongClickListener:
  2. http://developer.android.com/reference/android/widget/AdapterView.html#setOnItemLongClickListener%28android.widget.AdapterView.OnItemLongClickListener%29

    也就是说,你在整个ListView上设置一个OnItemLongClickListener - 它有一个方法:

    public abstract boolean onItemLongClick (AdapterView<?> parent, View view, int position, long id)
    
    只要长按ListView中的项目,就会调用

    。如您所见,该方法还接收长按项目的位置,然后您可以相应地处理点击。

    1. 如果你真的需要在每个项目中只需要长按一次TextView(而不是解决方案1中的整个项目),你需要在适配器的getView方法中设置监听器创建列表项视图。

      也就是说,您继承了SimpleCursorAdapter并覆盖了getView方法。在那里,您可以扩展XML布局,获取对TextView的引用并设置OnLongClickListener。在这种情况下,由于您是单独为每个项目执行此操作,因此findViewById将起作用,因为您位于视图树的子树中,其中确实只有一个具有ID R.id.overViewFooName的View。

答案 1 :(得分:0)

我在调试器中测试了这个,当我长时间点击列表时触发了事件。

public class OverviewFragment extends ListFragment implements 
LoaderManager.LoaderCallbacks<Cursor>
,OnItemLongClickListener
{

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    //notice the adapter is setup in onCreate
    adapter2 = new CustomListViewAdapter(this, R.id.list_item, summary,
            mSortOrder, tabsList);
    setListAdapter(adapter2);
}


@Override
public void onActivityCreated(Bundle savedState) {
    super.onActivityCreated(savedState);
    getListView().setOnItemLongClickListener(this);
    //registerForContextMenu(getListView());
}


@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
        int position, long id) {
    // TODO Auto-generated method stub
    return false;
}