Home > Software engineering >  Fetching JSON data returns null in fragment of a tablayout
Fetching JSON data returns null in fragment of a tablayout

Time:02-20

My DynamicFragment.java is as below

public class DynamicFragment extends Fragment {

public static DynamicFragment newInstance() {
    return new DynamicFragment();
}

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

// adding the layout with inflater
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_dynamic, container, false);
    initViews(view);
    return view;
}

// initialise the categories
private void initViews(View view) {
    TextView textView = view.findViewById(R.id.commonTextView);
    textView.setText(String.valueOf("Category : "   getArguments().getInt("position")));

    TextView userName = view.findViewById(R.id.userName);
    userName.setText("Name :"   getArguments().getString("name"));

}

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

@Override
public void onAttach(Context context) {
    super.onAttach(context);
}

// pause function call
@Override
public void onPause() {
    super.onPause();
}

// resume function call
@Override
public void onResume() {
    super.onResume();
}

// stop when we close
@Override
public void onStop() {
    super.onStop();
}

// destroy the view
@Override
public void onDestroyView() {
    super.onDestroyView();
}

@Override
public void onDestroy() {
    super.onDestroy();
  }
}

DynamicFragmentAdapter.java is below:

public class DynamicFragmentAdapter extends FragmentStatePagerAdapter {
private int mNumOfTabs;

DynamicFragmentAdapter(FragmentManager fm, int NumOfTabs) {
    super(fm);
    this.mNumOfTabs = NumOfTabs;
}

// get the current item with position number
@Override
public Fragment getItem(int position) {
    Bundle b = new Bundle();
    b.putInt("position", position);
    Fragment frag = DynamicFragment.newInstance();
    frag.setArguments(b);
    return frag;
}

// get total number of tabs
@Override
public int getCount() {
    return mNumOfTabs;
}
}

DynamicActivity.java is as below:

public class DynamicActivity extends AppCompatActivity {

private ViewPager viewPager;
private TabLayout mTabLayout;

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

private void initViews() {

    // initialise the layout
    viewPager = findViewById(R.id.viewpager);
    mTabLayout = findViewById(R.id.tabs);

    // setOffscreenPageLimit means number
    // of tabs to be shown in one page
    viewPager.setOffscreenPageLimit(5);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
    mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            // setCurrentItem as the tab position
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
    setDynamicFragmentToTabLayout();
}

// show all the tab using DynamicFragmnetAdapter
private void setDynamicFragmentToTabLayout() {

    try {
        // get JSONObject from JSON file
        JSONObject obj = new JSONObject(loadJSONFromAsset());
        // fetch JSONArray named contacts
        JSONArray userArray = obj.getJSONArray("contacts");
        int arrayLength = userArray.length();

        // implement for loop for getting users list data
        for (int i = 0; i < arrayLength; i  ) {

            // create a JSONObject for fetching single user data
           JSONObject userDetail = userArray.getJSONObject(i);
            // fetch name and store it in arraylist
           
            MainActivity.personNames.add(userDetail.getString("name"));

            // set the tab name as "Page: "   i
            mTabLayout.addTab(mTabLayout.newTab().setText("Page:"   i));

        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

    DynamicFragmentAdapter mDynamicFragmentAdapter = new DynamicFragmentAdapter(getSupportFragmentManager(), mTabLayout.getTabCount());

    // set the adapter
    viewPager.setAdapter(mDynamicFragmentAdapter);

    // set the current item as 0 (when app opens for first time)
    viewPager.setCurrentItem(0);

}

public String loadJSONFromAsset() {
    String json = null;
    try {
        InputStream is = getAssets().open("contact_data.json");
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        json = new String(buffer, "UTF-8");
    } catch (IOException ex) {
        ex.printStackTrace();
        return null;
    }
    return json;
}
}

The name does not load from JSON and shows as "null" in fragment though I've defined the TextView userName in fragment_dynamic.xml as below

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">

<TextView
    android:id="@ id/commonTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="zxjhcvzxvchjzxbhj"
    android:textColor="@color/purple_500"
    android:textStyle="bold" />
<TextView
    android:id="@ id/userName"
    android:layout_below="@id/commonTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="zxjhcvzxvchjzxbhj"
    android:textColor="@color/purple_500"
    android:textStyle="bold" />

</RelativeLayout>

My truncated contacts.json is as below:

    {
  "contacts": [

{
  "id": "1",
  "name": "Amitabh"
  "age": "25"
},

{
  "id": "2",
  "name": "Amit"
  "age": "30"
  }  
 ]
 }

The position number of the tab updates correctly as I swipe through the fragments, from the FOR Loop but the name shows as "null" in all the fragments. I am new to the JSON concepts and its use in Fragments and Tablayouts. Any help in this regard will be of great help.

I think the variable names in my JSON data are not linked with the variables in the java class and don't know how to do it.

Thanks in advance!

CodePudding user response:

Try to store the personNames in a local variable and pass it to the adapter:

    ArrayList<String> personNames = new ArrayList<String>()
    
    try {
        // get JSONObject from JSON file
        JSONObject obj = new JSONObject(loadJSONFromAsset());
        // fetch JSONArray named contacts
        JSONArray userArray = obj.getJSONArray("contacts");
        int arrayLength = userArray.length();

        // implement for loop for getting users list data
        for (int i = 0; i < arrayLength; i  ) {

            // create a JSONObject for fetching single user data
           JSONObject userDetail = userArray.getJSONObject(i);
            // fetch name and store it in arraylist
           
            personNames.add(userDetail.getString("name"));

            // set the tab name as "Page: "   i
            mTabLayout.addTab(mTabLayout.newTab().setText("Page:"   i));

        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

    DynamicFragmentAdapter mDynamicFragmentAdapter = new DynamicFragmentAdapter(getSupportFragmentManager(), mTabLayout.getTabCount(), personNames);

    // set the adapter
    viewPager.setAdapter(mDynamicFragmentAdapter);

Then, from the adapter, pass the name argument down to the DynamicFragment:

public class DynamicFragmentAdapter extends FragmentStatePagerAdapter {
    private int mNumOfTabs;
    private ArrayList<String> personNames;

    DynamicFragmentAdapter(FragmentManager fm, int NumOfTabs, ArrayList<String> personNames) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
        this.personNames = personNames;
    }

    // get the current item with position number
    @Override
    public Fragment getItem(int position) {
        Bundle b = new Bundle();
        b.putInt("position", position);
        b.putString("name", personNames[position])
        Fragment frag = DynamicFragment.newInstance();
        frag.setArguments(b);
        return frag;
    }

Finally, you should be able to access the name in the Fragment using (like you where doing):

getArguments().getString("name")
  • Related