user6456773
user6456773

Reputation: 381

How to load respective JSON in a Spinner?

I have 2 Spinners and 2 respective .json files. The first Spinner holds the category, the second the subcategory. I need to load the respective data when the specific category is chosen.

Category JSON file:

{
    "Categories": {
        "Category": [{
            "cat_id": 1,
            "cat_title": "..."
        }, {
            "cat_id": 2,
            "cat_title": "..."
        }, {
            "cat_id": 3,
            "cat_title": "..."
        }]
    }
}

Subcategory JSON file:

{
    "Subcategories": {
        "Subcategory": [{
            "cat_id": 1,
            "subcat_id": 1,
            "subcat_title": ".."
        }]
    }
}

They are linked on the cat id. The loading is controlled by identical methods.

Here is the method for the category:

private void prepareCats() {

    inputStream = getResources().openRawResource(R.raw.categories);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    try {
        ctr = inputStream.read();
        while (ctr != -1) {
            byteArrayOutputStream.write(ctr);
            ctr = inputStream.read();
        }
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        // Parse the data into jsonobject to get original data in form of json.
        JSONObject jObject = new JSONObject(
                byteArrayOutputStream.toString());

        JSONObject jObjectResult = jObject.getJSONObject("Categories");
        JSONArray jArray = jObjectResult.getJSONArray("Category");
        String cat_title = "";

        for(int i=0;i<jArray.length();i++){


            cat.setCatname(jArray.getJSONObject(i).getString("cat_title"));
            cat.setCatId(jArray.getJSONObject(i).getString("cat_id"));

            Log.v("cat",cat.getCatname());

            categories.setOnItemSelectedListener(new OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                    System.out.println("cat position" + position);
                    catPosition = position;
                }

                @Override
                public void onNothingSelected(AdapterView<?> parentView) {
                    // your code here
                }

            });
            categoriesList.add(cat.getCatname());

            ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout
                    .simple_spinner_item, categoriesList);

            categories.setAdapter(
                    new NothingSelectedSpinnerAdapter(
                            dataAdapter,
                            R.layout.contact_spinner_cat_row_nothing_selected,
                            this));
            dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        }

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

And for loading subcategory:

 private void prepareSubCats() {
    inputStream = getResources().openRawResource(R.raw.subcategories);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    try {
        ctr = inputStream.read();
        while (ctr != -1) {
            byteArrayOutputStream.write(ctr);
            ctr = inputStream.read();
        }
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }



    try {
        // Parse the data into jsonobject to get original data in form of json.
        JSONObject jObject = new JSONObject(
                byteArrayOutputStream.toString());

        JSONObject jObjectResult = jObject.getJSONObject("Subcategories");
        JSONArray jArray = jObjectResult.getJSONArray("Subcategory");
        String subcat_title = "";

        for(int i=0;i<jArray.length();i++){
            subcat.setSubCatname(jArray.getJSONObject(i).getString("subcat_title"));
            subcat.setCatId(jArray.getJSONObject(i).getString("cat_id"));

            subcategoriesList.add(subcat.getSubCatname());

            subCategories.setOnItemSelectedListener(new OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                    subcatPosition = position;

                }

                @Override
                public void onNothingSelected(AdapterView<?> parentView) {
                    // your code here
                }

            });

            ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout
                    .simple_spinner_item, subcategoriesList);

            subCategories.setAdapter(
                    new NothingSelectedSpinnerAdapter(
                            dataAdapter,
                            R.layout.contact_spinner_subcat_row_nothing_selected,
                            this));
            dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        }

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

}

What I need is to compare the category's cat id and the subcategory's cat id, so that the subcategories to be filled up to the according category.

Upvotes: 0

Views: 391

Answers (2)

Mohsen Mirhoseini
Mohsen Mirhoseini

Reputation: 8862

Here is my suggestion while I have done some improvement to you code using Gson and Butterknife libraries which you can study more about.

here is the sample MainActivity:

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.category)
    Spinner categorySpinner;
    @BindView(R.id.subcategory)
    Spinner subcategorySpinner;
    private CategoriesModel categories;
    private SubcategoriesModel subcategories;

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

        ButterKnife.bind(this);

        loadCategoriesData();

        prepareCategories();

    }

    private void loadCategoriesData() {
        // load categories using Gson
        InputStream categoriesInputStream = getResources().openRawResource(R.raw.categories);
        Reader categoriesReader = new BufferedReader(new InputStreamReader(categoriesInputStream));
        categories = new Gson().fromJson(categoriesReader, CategoriesModel.class);

        // load subcategories using Gson
        InputStream inputStream = getResources().openRawResource(R.raw.subcategories);
        Reader reader = new BufferedReader(new InputStreamReader(inputStream));
        subcategories = new Gson().fromJson(reader, SubcategoriesModel.class);
    }

    private void prepareCategories() {
        ArrayAdapter<Category> categoriesArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, categories.getCategories().getCategories());
        categorySpinner.setAdapter(categoriesArrayAdapter);

        categorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                // prepare subcategories using selected category
                prepareSubcategories((Category) parent.getItemAtPosition(position));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                subcategorySpinner.setEnabled(false);
            }
        });
    }

    private void prepareSubcategories(Category category) {
        // filter subcategories using selected category
        ArrayList filteredSubcategories = new ArrayList();
        for (Subcategory subcategory : subcategories.getSubcategories().getSubcategories()) {
            if (subcategory.getCategoryId() == category.getCatId())
                filteredSubcategories.add(subcategory);
        }

        ArrayAdapter<Subcategory> subcategoriesArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, filteredSubcategories);
        subcategorySpinner.setAdapter(subcategoriesArrayAdapter);

        subcategorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                // do what ever you want with the selected item :)
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }
}

and here are POJO Models to handle values.

CategoriesModel.java:

public class CategoriesModel {

    @SerializedName("Categories")
    @Expose
    private Categories categories;

    public Categories getCategories() {
        return categories;
    }

    public void setCategories(Categories categories) {
        this.categories = categories;
    }

    public class Categories {

        @SerializedName("Category")
        @Expose
        private List<Category> categories = new ArrayList<>();

        public List<Category> getCategories() {
            return categories;
        }

        public void setCategories(List<Category> categories) {
            this.categories = categories;
        }

    }
}

Category.java:

public class Category {

    @SerializedName("cat_id")
    @Expose
    private Integer catId;
    @SerializedName("cat_title")
    @Expose
    private String catTitle;

    public Integer getCatId() {
        return catId;
    }

    public void setCatId(Integer catId) {
        this.catId = catId;
    }

    public String getCatTitle() {
        return catTitle;
    }

    public void setCatTitle(String catTitle) {
        this.catTitle = catTitle;
    }

    @Override
    public String toString() {
        return catTitle;
    }
}

SubcategoriesModel.java:

public class SubcategoriesModel {

    @SerializedName("Subcategories")
    @Expose
    private Subcategories subcategories;

    public Subcategories getSubcategories() {
        return subcategories;
    }

    public void setSubcategories(Subcategories subcategories) {
        this.subcategories = subcategories;
    }

    public class Subcategories {

        @SerializedName("Subcategory")
        @Expose
        private List<Subcategory> subcategories = new ArrayList<Subcategory>();

        public List<Subcategory> getSubcategories() {
            return subcategories;
        }

        public void setSubcategories(List<Subcategory> subcategories) {
            this.subcategories = subcategories;
        }
    }
}

Subcategory.java:

public class Subcategory {

    @SerializedName("cat_id")
    @Expose
    private Integer categoryId;
    @SerializedName("subcat_id")
    @Expose
    private Integer subcategoryId;
    @SerializedName("subcat_title")
    @Expose
    private String subcategoryTitle;

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public Integer getSubcategoryId() {
        return subcategoryId;
    }

    public void setSubcategoryId(Integer subcategoryId) {
        this.subcategoryId = subcategoryId;
    }

    public String getSubcategoryTitle() {
        return subcategoryTitle;
    }

    public void setSubcategoryTitle(String subcategoryTitle) {
        this.subcategoryTitle = subcategoryTitle;
    }

    @Override
    public String toString() {
        return subcategoryTitle;
    }
}

hope it helps ;)

Upvotes: 0

jonathanrz
jonathanrz

Reputation: 4296

You already are using the setOnItemSelectedListener in the subcategory spinner, you just need to implement the same in the category spinner.

When the OnItemSelectedListener of the category spinner is triggered, you should update the subcategory adapter.

More info here: Android Spinner: Get the selected item change event

-- Edit --

The solution for your problem is the following:

1-in the OnItemSelected of the category spinner, when you get the category position, you need to call the prepareSubcategories spinner to update the subcategories.

2-in the prepareSubcategories, you need to get the Category id of the Category that are in the category position variable.

3-you need to filter the subcategories list to remove the subcategories that don't have the cat_id.

Upvotes: 1

Related Questions