1

我正在寫一個FragmentActivity在那裏我有一個ListFragment(使用SimpleCursorAdapter),一個detailsFragmentdetailActivity(當手機處於縱向即用,嵌入detailsFragment)。
當我點擊列表中的一個項目時,它應該使用來自第二個遊標的數​​據填充detailFragment,該數據使用所選項目的_id作爲selectionArgs構建。
但是,在_id似乎沒有通過,我得到了ListFragment舉杯,我顯示所選項目的_id(它是正確的),但在detailsFragment_id從來沒有到達(它仍然等於0,發送NullPointerException)。 我錯在哪裏?SimpleCursorAdapter.getItemId()爲detailFragment。如何通過_id?

編輯:我忘了說還有,當我從返回按鈕的細節活動回來,列表是空的,它說了一些關於數據庫被關閉。
Logcat消息可以在我的文章末尾找到。

父活動

package com.gmail.david.corsalini.sportscout; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 

public class MatchesRugbyPage extends FragmentActivity { 

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

MatchesListFragment(我的ListFragment)

package com.gmail.david.corsalini.sportscout; 

import android.content.Intent; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.support.v4.app.FragmentTransaction; 
import android.support.v4.app.ListFragment; 
import android.util.Log; 
import android.view.View; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 
import android.widget.Toast; 

/** 
* This is the "top-level" fragment, showing a list of items that the user can 
* pick. Upon picking an item, it takes care of displaying the data to the user 
* as appropriate based on the current UI layout. 
*/ 
public class MatchesListFragment extends ListFragment { 
    boolean mDualPane; 
    private Cursor cursor; 
    private SimpleCursorAdapter myAdapter; 
    private long MATCH_ID; 
    private int selected; 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     // Database 
     DBSportScout db = new DBSportScout(getActivity()); 
     db.open(); 
     // Cursor 
     String[] selection = { DBSportScout.MatchMetaData.KEY_MNAME, 
       DBSportScout.MatchMetaData.KEY_MROWID }; 
     cursor = db.fetch(DBSportScout.MatchMetaData.DATABASE_TABLE_MATCH, 
       selection, null, null, null, null, null, null); 
     getActivity().startManagingCursor(cursor); 
     // Adapter 
     String[] columns = { DBSportScout.MatchMetaData.KEY_MNAME }; 
     int[] to = { R.id.tv1ListItem }; 
     myAdapter = new SimpleCursorAdapter(getActivity(), 
       R.layout.ss_list_item, cursor, columns, to); 
     setListAdapter(myAdapter); 
     db.close(); 

     // Check to see if we have a frame in which to embed the details 
     // fragment directly in the containing UI. 
     View detailsFrame = getActivity().findViewById(R.id.detailsFrame); 
     mDualPane = detailsFrame != null 
       && detailsFrame.getVisibility() == View.VISIBLE; 

     if (savedInstanceState != null) { 
      // Restore last state for checked position. 
      MATCH_ID = savedInstanceState.getLong("curChoice", 0); 
     } 

     if (mDualPane) { 
      // In dual-pane mode, the list view highlights the selected item. 
      getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
      // Make sure our UI is in the correct state. 
      showDetails(MATCH_ID); 
     } 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putLong("curChoice", MATCH_ID); 
    } 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     selected = position; 
     MATCH_ID = myAdapter.getItemId(position); 
     Toast.makeText(getActivity(), "Partita n. " + Long.toString(MATCH_ID), 
       Toast.LENGTH_SHORT).show(); 
     showDetails(MATCH_ID); 
     Log.i("Partita", "ID Partita selezionata= " + MATCH_ID); 
    } 

    /** 
    * Helper function to show the details of a selected item, either by 
    * displaying a fragment in-place in the current UI, or starting a whole new 
    * activity in which it is displayed. 
    */ 

    public void showDetails(long matchid) { 

     if (mDualPane) { 
      // We can display everything in-place with fragments, so update 
      // the list to highlight the selected item and show the data. 
      getListView().setItemChecked(selected, true); 

      // Check what fragment is currently shown, replace if needed. 
      MatchDetailsFragment f = (MatchDetailsFragment) getFragmentManager() 
        .findFragmentById(R.id.detailsFrame); 
      if (f == null || f.getMATCH_ID() != matchid) { 
       // Make new fragment to show this selection. 
       f = new MatchDetailsFragment(); 

       // Supply index input as an argument. 
       Bundle args = new Bundle(); 
       args.putLong("matchid", matchid); 
       f.setArguments(args); 

       // Execute a transaction, replacing any existing fragment 
       // with this one inside the frame. 
       FragmentTransaction ft = getFragmentManager() 
         .beginTransaction(); 
       ft.replace(R.id.detailsFrame, f); 
       ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 
       ft.addToBackStack(null); 
       ft.commit(); 
      } 

     } else { 
      // Otherwise we need to launch a new activity to display 
      // the dialog fragment with selected text. 
      Intent intent = new Intent(); 
      intent.setClass(getActivity(), MatchDetailsActivity.class); 
      intent.putExtra("index", matchid); 
      startActivity(intent); 
     } 
    } 

} 

MatchDetailFragment(我的detailsFragment)

package com.gmail.david.corsalini.sportscout; 

import com.gmail.david.corsalini.sportscout.DBSportScout.MatchMetaData; 

import android.database.Cursor; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 
import android.widget.Toast; 

/** 
* This is the secondary fragment, displaying the details of a particular item. 
*/ 
public class MatchDetailsFragment extends Fragment { 

    /** 
    * Create a new instance of DetailsFragment, initialized to show the text at 
    * 'matchid'. 
    */ 
    public static MatchDetailsFragment newInstance(long matchid) { 
     MatchDetailsFragment f = new MatchDetailsFragment(); 

     // Supply index input as an argument. 
     Bundle args = new Bundle(); 
     args.putLong("matchid", matchid); 
     f.setArguments(args); 
     return f; 
    } 

    private TextView tvfTriesA; 
    private TextView tvfTriesB; 
    private TextView tvfName; 
    private long MATCH_ID; 
    public long getMATCH_ID() { 
     MATCH_ID = getArguments().getLong("matchid", 0); 
     return MATCH_ID; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     if (container == null) { 
      // We have different layouts, and in one of them this 
      // fragment's containing frame doesn't exist. The fragment 
      // may still be created from its saved state, but there is 
      // no reason to try to create its view hierarchy because it 
      // won't be displayed. Note this is not needed -- we could 
      // just run the code below, where we would create and return 
      // the view hierarchy; it would just never be used. 
      return null; 
     } 
     View view = inflater.inflate(R.layout.match_summary, container, false); 
     populateDetails(MATCH_ID); 
     return view; 
    } 

    public void populateDetails(long matchid) { 

     // Create textviews 
     tvfName = (TextView) getActivity().findViewById(R.id.tvfName); 
     tvfTriesA = (TextView) getActivity().findViewById(R.id.tvfTriesA); 
     tvfTriesB = (TextView) getActivity().findViewById(R.id.tvfTriesB); 
     tvfName.setText(Long.toString(MATCH_ID)); 

     // Populate textviews 
     DBSportScout db = new DBSportScout(getActivity()); 
     db.open(); 
     String selectionmatchid = Long.toString(matchid); 
     String[] columns = { DBSportScout.MatchMetaData.KEY_MNAME, 
       DBSportScout.MatchMetaData.KEY_MDATE, 
       DBSportScout.MatchMetaData.KEY_MSTATUS, 
       DBSportScout.MatchMetaData.KEY_MSUMMARY, 
       DBSportScout.MatchMetaData.KEY_MTEAM_A_ID, 
       DBSportScout.MatchMetaData.KEY_MTEAM_B_ID, 
       DBSportScout.MatchMetaData.KEY_MCHAMP_ID, 
       DBSportScout.MatchMetaData.KEY_MTURN, 
       DBSportScout.MatchMetaData.KEY_MSPORT_ID, 
       DBSportScout.MatchMetaData.KEY_MSCORE_A, 
       DBSportScout.MatchMetaData.KEY_MSCORE_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT1_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT1_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT2_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT2_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT3_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT3_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT4_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT4_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT5_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT5_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT6_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT6_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT7_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT7_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT8_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT8_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT9_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT9_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT10_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT10_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT11_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT11_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT12_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT12_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT13_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT13_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT14_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT14_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT15_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT15_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT16_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT16_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT17_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT17_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT18_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT18_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT19_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT19_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT20_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT20_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT21_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT21_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT22_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT22_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT23_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT23_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT24_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT24_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT25_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT25_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT26_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT26_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT27_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT27_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT28_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT28_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT29_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT29_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT30_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT30_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT31_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT31_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT32_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT32_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT33_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT33_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT34_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT34_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT35_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT35_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT36_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT36_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT37_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT37_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT38_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT38_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT39_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT39_B, 
       DBSportScout.MatchMetaData.KEY_MSTAT40_A, 
       DBSportScout.MatchMetaData.KEY_MSTAT40_B }; 
     String[] selectionArgs = { selectionmatchid }; 

     Cursor c = db.fetch(DBSportScout.MatchMetaData.DATABASE_TABLE_MATCH, 
       columns, DBSportScout.MatchMetaData.KEY_MROWID + "=?", 
       selectionArgs, null, null, null, null); 
     c.moveToFirst(); 

     tvfName.setText(c.getInt(c.getColumnIndexOrThrow(DBSportScout.MatchMetaData.KEY_MNAME))); 
     tvfTriesA.setText(c.getInt(c.getColumnIndexOrThrow(DBSportScout.MatchMetaData.KEY_MSTAT1_A))); 
     tvfTriesB.setText(c.getInt(c.getColumnIndexOrThrow(DBSportScout.MatchMetaData.KEY_MSTAT1_B))); 
     db.close(); 
    } 
} 

fetch()方法從DBSportScout

public Cursor fetch(String table, String[] columns, String selection, 
     String[] args, String groupby, String having, String orderby, 
     String limit) { // metodo per fare la query di tutti i dati 
    Cursor cursor = mDb.query(table, columns, selection, args, groupby, 
      having, orderby, limit); 
    if (cursor != null) { 
     cursor.moveToFirst(); 
    } 
    return cursor; 
} 

最後這裏是logcat的

FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gmail.david.corsalini.sportscout/com.gmail.david.corsalini.sportscout.MatchesRugbyPage}: java.lang.NullPointerException 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 
    at android.app.ActivityThread.access$600(ActivityThread.java:123) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4424) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException 
    at com.gmail.david.corsalini.sportscout.MatchDetailsFragment.populateDetails(MatchDetailsFragment.java:77) 
    at com.gmail.david.corsalini.sportscout.MatchDetailsFragment.onCreateView(MatchDetailsFragment.java:64) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:870) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) 
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:505) 
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1133) 
    at android.app.Activity.performStart(Activity.java:4475) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1929) 
    ... 11 more 

回答

0

我從來沒有使用過套餐,除非我開始一項新的活動。我通常所做的(並且我沒有聲稱這是最好的方法,但它適用於我)是定義一個公共靜態變量來保存行ID,然後使用它。

一個例子(只是相關的位)。

片段1(會員):

public static Long mRowId; 

@Override 
public void onListItemClick(ListView l, View v, int position, long id) { 
    mRowId = id; 
    MemberDisplayFragment memberdisplay = new MemberDisplayFragment(); 
    getFragmentManager().beginTransaction().replace(R.id.rightpane, memberdisplay).commit(); 
} 

片段2(會員詳細信息顯示):

Cursor memberdisplay = mDbHelper.fetchMember(MemberListFragment.mRowId); 
getActivity().startManagingCursor(memberdisplay); 
memberdisplay.moveToFirst(); 

希望這有助於!

+0

這似乎是正確的,所以我改變了詳細信息片段中的getMATCH_ID()方法爲MATCH_ID = MatchesListFragment.MATCH_ID;返回MATCH_ID; 然後我把MATCH_ID = getMATCH_ID();在populateDetails()(第一行),但我在tvfName.setText(Long.toString(MATCH_ID))得到一個nullpointerexception;我無法解釋! –

+0

試試這個:完全丟失getMATCH_ID方法,只要需要它就從原始片段中引用MATCH_ID。設置'tvfName.setText(Long.toString(MatchesListFragment.MATCH_ID));'看看會發生什麼。 – Barak

+0

還是那種令人討厭的零污染!我不明白,在listfrag中的MATCH_ID設置正確(我知道,因爲我有一個if(MATCH_ID!= 0)在populateDetails的開頭,所以我可以至少達到listFrag並單擊該項目,顯示正確_id),我只是要求他把它翻譯成字符串並顯示出來。 TextView存在並初始化。 –

0

當您查詢,您不要在投影

String[] selection= {DBSportScout.MatchMetaData.KEY_MNAME, DBSportScout.MatchMetaData.KEY_MROWID }; 

所以索要_ID列,它會永遠是零,我覺得也許你需要覆蓋你的適配器來返回你選擇的ID,或者在你的表中添加一個_id列。

+0

KEY_MROWID =「_id」 這是我創建表格時的一個列。事實上,當我點擊列表中的項目時,敬酒將返回項目的正確_id,但它永遠不會傳遞給其他片段。 –