0

다음 클래스를 작성하여 사용자 지정 목록 행이있는 목록보기를 만들었습니다. 저는 Android Support Library v4을 프로젝트에 사용하고 ActionBarSherlock 라이브러리를 사용하여 이전 장치 용 작업 표시 줄을 통합합니다.ListFragment : CursorAdapter의 findViewById가 null을 반환합니다.

public class CustomListActivity extends SherlockFragmentActivity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     setTheme(R.style.Sherlock___Theme_DarkActionBar); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.fragment_list); 
    } 
} 

...

public class ListFragment extends SherlockListFragment implements LoaderCallbacks<Cursor> { 
    private Activity mActivity; 
    private CursorAdapter mAdapter; 
    // Query parameter as members ... 
    private String mFromColumns; 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     setEmptyText("No data to display"); 
     mActivity = getActivity(); 
     // Query parameters are stored in members here ... 
     mFromColumns = { "_id", "name" }; 
     mAdapter = new CustomCursorAdapter(mActivity, null, 0); 
     setListAdapter(mAdapter); 
     getLoaderManager().initLoader(0, null, this); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle extras) { 
     return new CursorLoader(mActivity, mUri, mFromColumns, mSelection, mSelectionArgs, sortOrder); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
     mAdapter.swapCursor(cursor); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     mAdapter.swapCursor(null); 
    } 
} 

...

public class CustomCursorAdapter extends CursorAdapter { 
    private LayoutInflater mInflater; 

    public CustomCursorAdapter(Context context, Cursor cursor, int flags) { 
     super(context, cursor, flags); 
     mInflater = LayoutInflater.from(context); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     TextView listItem = (TextView)view.findViewById(R.id.name); 
//  TextView listItem = (TextView)view.findViewById(android.R.id.text1); 
     String text = cursor.getString(cursor.getColumnIndex("name")); 
     listItem.setText(text); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     return mInflater.inflate(R.layout.list_item, parent, false); 
//  return mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); 
    } 
} 

목록보기 성공적으로로드 내가 프레임 워크가 제공하는 목록 항목 및 레이아웃을 사용하는 경우, 데이터 행을 표시합니다 (주석 처리되지 않은 행은 CustomCursorAdapter). 그러나 사용자 정의 레이아웃 및 목록 항목을 사용하도록 회선을 바꿀 때 findViewByIdnull을 반환합니다. 다음은 xml 파일입니다.

fragment_list.xml

<?xml version="1.0" encoding="utf-8"?> 
<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
    android:name="com.example.app.fragment.ListFragment" 
    android:id="@+id/list_fragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

</fragment> 

list_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 
    <TextView 
     android:id="@+id/name" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 
    </TextView> 
</LinearLayout> 

나는 확신, 내가 XML 파일을 링크하거나 빌드 얼마나 얼마나 문제가 있습니다. 오류를 볼 수 있기를 바랍니다. 사실, 나는 list_item.xml가 목록보기의 행 레이아웃으로 사용되는 방법을 이해하지 못합니다. fragment_list.xml으로 설정된 유일한 참조 번호는 setContentView(R.layout.fragment_list);입니다. 그리고이 XML 파일에는 <ListView android:id="@android:id/list" />과 같은 컨테이너 요소가 없습니다 (다른 설정에서 보았습니다). 또한

:

나는 여전히 CursorAdapter 또는이 동작이 내장되어 이미있는 경우 ViewHolder 패턴을 사용하는 것이 좋습니다 알고 싶습니다. 다른 예제에서는 여러 번 보았지만 BaseAdapter 또는 SimpleCursorAdapter에서 상속 된 예제를 보았습니다.


교훈 : 나는이 문제를 해결하기 위해 노력하고있는 동안

, 내가 somewhen XML 파일 설정을 권리가 있었다. 하지만 또 다른 일은 저에게 물건을 달리는 것을 방해했습니다. 여기 당신이 알아야 할 것이 있습니다.
행 레이아웃에 여러 정보 을 표시하려면 CursorLoaderfromColumn 매개 변수에 연관된 열 이름을 포함시켜야합니다. 그렇지 않으면, 당신은 예외로 실행됩니다 fromColumns에서

java.lang.IllegalStateException: get field slot from row 0 col -1 failed 

모든 열 이름 ...

String[] fromColumns = { "_id", "name", "comments" } 

... 관련을 당신의 커서를 물어 무엇을. 커서를 반복자로 사용하려면 _id 열이 필수입니다.

+0

동일한 null 문제가있었습니다. 방금 newView 메서드에서 생성자의 행 레이아웃이 동일하지 않다는 것을 알았습니다. 그래서 뷰를 팽창시킬 때 행 레이아웃에없는 id를 대상으로했습니다. –

답변

2

귀하의 코드는 모두 나를 위해 (회선 설명을 변경했을 때와 마찬가지로) 작동합니다.유일한 것 : 공공 빈 생성자를 ListFragment에 추가했습니다.

그리고 여전히 ViewHolder 패턴을 CursorAdapter과 함께 사용하는 것이 좋습니다.

public void bindView(View view, Context context, Cursor cursor) { 
    ViewHolder holder = (ViewHolder) view.getTag(); 
    if (holder == null) { 
     holder = new ViewHolder(); 
     holder.name = (TextView) view.findViewById(R.id.name); 

     view.setTag(holder); 
    } 

    String text = cursor.getString(cursor.getColumnIndex("name")); 
    holder.name.setText(text); 
} 

private static class ViewHolder { 
    TextView name; 
} 
+0

위에서 언급 한대로 실제로 작동하는 주석 처리되지 않은 행을 인용했습니다. * ViewHolder * patterm에 관해서 : 내 코드와 함께 사용하는 방법에 대한 예제를 추가 할 수 있습니까? – JJD

+0

@JJD, 죄송합니다, 제 대답을 바로 잡았습니다. – StenaviN

+0

하루 종일 컴퓨터 앞에 앉아있을 때 일어납니다. Thankfully 히, 나는 어제 일찍 자야했다. 오늘 나는'.inflate (R.layout.wrong_xml, ...'.)에서 이전 XML 레이아웃을 참조했다는 것을 알아 냈습니다. 감사합니다, StenaviN. – JJD

관련 문제