2016-08-03 107 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的的父视图中的问题

相关问题