Question

I am creating and replacing a fragment inside another fragments onViewCreated

public void onViewCreated(View view, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onViewCreated(view, savedInstanceState);
        //add searchFragment to this fragment
        FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
        if(searchFragment==null)
            searchFragment=new SearchFragment();
        fragmentTransaction.replace(R.id.updateFragmentContainer, searchFragment).commit();

        if(searchFragment.getView()==null){
            Log.d("getView","of search view is null");//the control always reaches here
        }
        listView=(ListView)getActivity().findViewById(R.id.listView1);
        if(listView!=null)
            listView.setOnItemClickListener(onItemClickListener);//the control never reaches here
        else
            searchFragment.setUpdateItemClickListener(onItemClickListener);//this is a function in the saerchFragment class; there too the listview obtained by findViewbyId is null
    }

Now theres a listView in the searchFragment whose onItemClickListener i want to set in the parent fragment. I have tried a lot of ways as shown above but none of them work as the listView returned by findViewById is always null.

Also the searchFragment functionality works just fine when i remove all these null pointer exceptions caused due to the listView. I have also tried overriding the getView of the searchFragment and returning a reference of the view which was infalted during onCreateView but it too returned null.

EDIT SearchFragment class

import android.content.ContentProviderClient;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class SearchFragment extends Fragment {
    int rollNo;
    Button searchButton=null;
    EditText rollNoEditText=null;
    ListView listView=null;
    public SearchFragment() {
        // TODO Auto-generated constructor stub
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.fragment_search, null);
    }
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        rollNoEditText=(EditText)getView().findViewById(R.id.rollNoEditText1);
        searchButton=(Button)getView().findViewById(R.id.searchbutton1);
        if(searchButton!=null)
            searchButton.setOnClickListener(onClickListener);
        else
            Log.d("Search Button", "null");
        listView=(ListView)getView().findViewById(R.id.listView1);
    }
    View.OnClickListener onClickListener=new View.OnClickListener() {

        @SuppressWarnings("deprecation")
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(rollNoEditText.getText().length()>0){
                try{
                rollNo=Integer.parseInt(rollNoEditText.getText().toString());
                if(rollNo>0){
                    listView.setAdapter(
                            new SimpleCursorAdapter(getActivity(), // Context.
                                    R.layout.item_parent_student,
                                    getStudentCurosr(),
                                    new String[] { "name","rollno","class","marks" },
                                    // Parallel array of which template objects to bind to those
                                    // columns.
                                    new int[] {R.id.nameTextView2,R.id.rollNoTextView2,R.id.classTextView2,R.id.marksTextView2 }
                            ));
                }
                    //displayStudentInfo(rollNo);
                }catch(Exception e){
                    e.printStackTrace();
                    Toast.makeText(getActivity().getApplicationContext(), "Please type a valid integer value", Toast.LENGTH_SHORT).show();
                }
            }

        }
    };

    private Cursor getStudentCurosr() {
        // Run query
        Uri uri = Uri.parse("content://com.example.students.provider.studentcontentprovider/student/"+rollNo);
          Log.d("RollNO passed",""+rollNo);
          ContentProviderClient contentProviderClient = getActivity().getContentResolver().acquireContentProviderClient(uri );
          Cursor cur = null;
        try {
            cur = contentProviderClient.query(uri,null,null, null, null);
            return cur;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return cur;
    }


}
Was it helpful?

Solution

getView of Child Fragment returns null

Fragment transactions are asynchronous so your new SearchFragment which you'll use in that replace transaction will not have its view available yet(it will happen in the future after the onViewCreated() method finishes). You could pass the listener instance to the newly created SearchFragment instance and store inside it in a private field(in that setter you could also check and see if the ListView is available at that moment, if it is then also set the listener passed in). Then in one of SearchFragment's lifecycle methods(like onViewCreated()) check that OnItemClickListener field, if it's null then set it on the ListView widget.

However, something tells me you're approaching this the wrong way and you should let the SearchFragment set its own listener on the ListView and pass whatever events to the parent fragment through getParentFragment() method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top