2016-08-03 108 views
1

我開始與Android,只是瘋狂與多個片段的實現。 我在我的MainActivity中有兩個片段:QuestionDetail和QuestionListFragment。 當我使用片段事務來替換QuestionDetail片段,當有人點擊其中一個QuestionListFragment選項時,我得到一個NullPointerException錯誤。NullPointerException使用片段事務

我一直在試圖解決這個問題幾個小時。任何幫助是極大的讚賞。

QuestionDetail

public class QuestionListFragment extends Fragment{ 

private RecyclerView recView; 
public static QuestionAdapter adapter; 
private QuestionListener listener; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.fragment_question_list, container, false); 
    recView = (RecyclerView) v.findViewById(R.id.recView); 
    return v; 
} 

@Override 
public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); 
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    recView.setLayoutManager(layoutManager); 

    adapter = new QuestionAdapter(QuestionCatalog.getQuestionCatalog().getQuestionList().getList()); 
    adapter.setOnClickListener(new View.OnClickListener(){ 
     @Override 
     public void onClick(View v) { 
      if (listener!=null) { 
       listener.onQuestionListener(adapter.getItem(recView.getChildAdapterPosition(v))); 
      } 
     } 
    }); 
    recView.setAdapter(adapter); 
} 

public interface QuestionListener { 
    void onQuestionListener(Question q); 
} 

public void setQuestionListener(QuestionListener listener) { 
    this.listener=listener; 
} 

QuestionDetail

public class QuestionDetail extends Fragment { 
// We use an ID to know which Question we're using 
private long questionId; 

public QuestionDetail() { 
    // Required empty public constructor 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    return inflater.inflate(R.layout.fragment_question_detail, container, false); 
} 

@Override 
public void onStart() { 
    super.onStart(); 
    //Fragments don’t include findViewById(). To get a reference to a view, we use getView() 
    View view = getView(); 
    if (view != null) { 
     TextView title = (TextView) view.findViewById(R.id.textQuestion); 
     Question question = QuestionCatalog.getQuestionCatalog().getQuestionList().getList().get((int) questionId); 
     title.setText(question.getName()); 
     TextView kind = (TextView) view.findViewById(R.id.textKind); 
     kind.setText(question.getKind()); 
    } 
} 

public void showDetails(String texto) { 
    TextView txtName = (TextView)getView().findViewById(R.id.textQuestion); 
    TextView txtKind = (TextView)getView().findViewById(R.id.textKind); 
    txtName.setText(texto); 
    txtKind.setText(texto); 
    } 
} 

MainActivity

public class MainActivity extends AppCompatActivity implements QuestionListFragment.QuestionListener { 

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

    QuestionListFragment frg =(QuestionListFragment)getFragmentManager().findFragmentById(R.id.listFragment); 
    frg.setQuestionListener(this); 
} 

@Override 
public void onQuestionListener(Question q) { 
    Toast.makeText(this, "num: " + q.getName(), 
      Toast.LENGTH_LONG).show(); 
    FragmentTransaction t = getSupportFragmentManager().beginTransaction(); 
    QuestionDetail f1 = new QuestionDetail(); 
    f1.showDetails(q.getName()); 
    t.replace(R.id.detailFragment,f1); 
    t.addToBackStack(null); 
    t.commit(); 
} 

堆棧跟蹤

08-04 09:54:11.914 22277-22277/com.hfad.predictandwin E/AndroidRuntime: FATAL EXCEPTION: main 
                    java.lang.NullPointerException 
                     at com.hfad.predictandwin.Fragments.QuestionDetail.showDetails(QuestionDetail.java:50) 
                     at com.hfad.predictandwin.MainActivity.onQuestionListener(MainActivity.java:34) 
                     at com.hfad.predictandwin.Fragments.QuestionListFragment$1.onClick(QuestionListFragment.java:55) 
                     at com.hfad.predictandwin.QuestionAdapter.onClick(QuestionAdapter.java:61) 
                     at android.view.View.performClick(View.java:4475) 
                     at android.view.View$PerformClick.run(View.java:18786) 
                     at android.os.Handler.handleCallback(Handler.java:730) 
                     at android.os.Handler.dispatchMessage(Handler.java:92) 
                     at android.os.Looper.loop(Looper.java:176) 
                     at android.app.ActivityThread.main(ActivityThread.java:5419) 
                     at java.lang.reflect.Method.invokeNative(Native Method) 
                     at java.lang.reflect.Method.invoke(Method.java:525) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862) 
                     at dalvik.system.NativeStart.main(Native Method) 
+0

請張貼堆棧跟蹤 – Bostone

+0

對不起,我張貼 –

+1

您正在訪問的片段的視圖創建之前。你不能那樣做。而不是'f1.showDetails(q.getName());',將該名稱放入片段參數中,並使用'onCreateView'中的參數來填充視圖。 – njzk2

回答

0

首先,不要在onStart()使用getView() - 你不應該爲了獲得在這一點上。其次,你不應該從別處直接調用Fragment實例的方法,在你的案例f1.showDetails(q.getName());。在那裏,片段沒有觀點。在將參數加載到FragmentManager之前,請參閱Best practice for instantiating a new Android Fragment瞭解如何將參數傳遞到Fragment中。


下一點 - 你應該使用findViewByIdonCreateView就像你一樣的另一個片段類中初始化你的看法。例如,

private TextView txtName, txtKind; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View rootView = inflater.inflate(R.layout.fragment_question_detail, container, false); 

    txtName = (TextView) rootView.findViewById(R.id.textQuestion); 
    txtKind = (TextView) rootView.findViewById(R.id.textKind); 

    // TODO: Read the link how to use these 
    Bundle arguments = getArguments(); 

    Question question = QuestionCatalog.getQuestionCatalog() 
       .getQuestionList().getList().get((int) questionId); 
    showQuestion(question); 

    return view; 
} 

private void showQuestion(Question q) { 
    txtName.setText(q.getName()); 
    txtKind.setText(q.getKind()); 
} 
+0

非常感謝您的幫助。它現在有效。 –

0

QuestionListFragment

我們設置單擊偵聽recView,不適配器。您應該替換adapter.setOnClickListener

recView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recView, new ClickListener() { 
      @Override 
      public void onClick(View view, int position) { 
       // do something with position. 
      } 

      @Override 
      public void onLongClick(View view, int position) { 

      } 
     })); 

QuestionDetail

questionId沒有初始化的,但你必須在這行中使用它:基於堆棧跟蹤和你的代碼

Question question = QuestionCatalog.getQuestionCatalog().getQuestionList().getList().get((int) questionId); 
0

(不知道哪一個是你的QuestionDetail中的第50行)ether txtName或txtKind求值爲null(也許兩者),所以無論出於何種原因getView().findViewById(R.id.textQuestion)返回null。可能是因爲getView()在調用不會讓你TextView的的父視圖中的問題

相關問題