Android Spinner set custom adapter - java

I'm working on an Android App (Too order objects) for school and I want to make a Spinner with categories labels.
However, when a label is selected, I want to get the selected category's id too.
I already can get my data into JSON thanks for my webservice but I don't know how to do to make my own custom adapter for my spinner.
The JSON looks like this :
[{"id":"1","name":"VEHICULES","subcategories":
[
{"id":"1","name":"Voitures"},
{"id":"2","name":"Motos"},
{"id":"3","name":"Equipement auto"},
{"id":"4","name":"Equipement moto"},
{"id":"5","name":"Autres"}]
},
{"id":"2","name":"IMMOBILIER","subcategories":
[
{"id":"6","name":"Locations"},
{"id":"7","name":"Colocations"},
{"id":"8","name":"Autres"}]
}]
Searching to make my own adapter, I created a java class Categories like that :
public class Categories {
public int id;
public String name;
public Categories(int id, String name) {
this.id = id;
this.name = name;
}
}
And, on my fragment I can get my JSON and read it :
public class AttemptCategories extends AsyncTask<String, String, String> {
String categoriesURL = "http:blabla.com";
JSONArray dataJsonArr = null;
JSONArray dataJsonArr2 = null;
List<Categories> listCat = new ArrayList<>();
#Override
protected void onPreExecute() {}
#Override
protected String doInBackground(String... arg0Z) {
try {
JSONObject json = jsonParser.getJSONFromUrl(categoriesURL);
dataJsonArr = json.getJSONArray("categories");
for (int i = 0; i < dataJsonArr.length(); i++) {
JSONObject c = dataJsonArr.getJSONObject(i);
Categories cat = new Categories(Integer.parseInt(c.getString("id")), c.getString("name"));
listCat.add(cat);
dataJsonArr2 = c.getJSONArray("subcategories");
for(int j = 0; j < dataJsonArr2.length(); j++) {
JSONObject s = dataJsonArr2.getJSONObject(j);
Categories subcat = new Categories(Integer.parseInt(s.getString("id")), s.getString("name"));
listCat.add(subcat);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String strFromDoInBg) {
adapter = new ArrayAdapter<>(getActivity().getApplicationContext(), 0, listCat);
sCategories.setAdapter(adapter);
}
}
When I try to load the page in which I want to see my spinner, my application crash... I tried it into debug mod but no exception appeared.
Does somebody know what is wrong or how can I resolve my problem please?

Related

How to create dynamically class in Android

In my application, I should use Material Stepper and for this, I want to use this library : https://github.com/ernestoyaquello/VerticalStepperForm
But I want to add this dynamically from server.
For connecting with server I used Retrofit library and I should check the type of items from server.
when this type is "penny" show one of this steps and when the type is "best" show another step.
I create this steps from library tutorials, but i want when type is penny show me StepDynamicTxt and when the type is best show me StepDynamicEdt!
I write below codes but just add one of the items from each step!
But in API, I have 2 item of penny types and 3 items of best type!
Should show me 5 step, but show me 2 step!
My codes :
public class StepperActivity extends AppCompatActivity {
private ApiServices apiServices;
private ProgressBar loader;
private VerticalStepperFormView stepper;
private StepDynamicEdt stepDynamicEdt;
private StepDynamicTxt stepDynamicTxt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bidzila_stepper);
//Initialize
apiServices = ApiClient.ApiClient().create(ApiServices.class);
loader = findViewById(R.id.bidStepper_loader);
stepper = findViewById(R.id.bidStepper);
//Api
callAPi();
}
private void callAPi() {
loader.setVisibility(View.VISIBLE);
Call<TodayResponse> call = apiServices.TODAY_RESPONSE_CALL(5);
call.enqueue(new Callback<TodayResponse>() {
#Override
public void onResponse(Call<TodayResponse> call, Response<TodayResponse> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
if (response.body().getRes() != null) {
if (response.body().getRes().getToday().size() > 0) {
loader.setVisibility(View.GONE);
//Foreach
for (int i = 0; i < response.body().getRes().getToday().size(); i++) {
if (response.body().getRes().getToday().get(i).getType().equals("penny")) {
stepDynamicEdt = new StepDynamicEdt(response.body().getRes().getToday().get(i).getName());
} else if (response.body().getRes().getToday().get(i).getType().equals("best")) {
stepDynamicTxt = new StepDynamicTxt(response.body().getRes().getToday().get(i).getName());
}
}
stepper.setup(new StepperFormListener() {
#Override
public void onCompletedForm() {
}
#Override
public void onCancelledForm() {
}
}, stepDynamicEdt, stepDynamicTxt)
.allowNonLinearNavigation(false)
.displayCancelButtonInLastStep(false)
.displayBottomNavigation(false)
.confirmationStepTitle("Confirm")
.stepNextButtonText("Continue")
.lastStepNextButtonText("Finish")
.includeConfirmationStep(false)
.init();
}
}
}
}
}
#Override
public void onFailure(Call<TodayResponse> call, Throwable t) {
Log.e("ResponseErr", t.getMessage());
}
});
}
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase));
}
}
I think this problem for this line:}, stepDynamicEdt, stepDynamicTxt) because just add 2 step.
How can i add this step dynamically in Android?
In your code, you are making a very fundamental mistake. And that is, you are using the same variable each time in your loop to store dynamic edit type and dynamic text type, which will replace any previously created fields. And hence when you finally create them, you end up with single last values of each type.
What you can do is, create a List with type Step, add new type every time you get them, and finally pass that list to the builder.
The builder accepts a list too, you should check implementation when its open source.
// before the for loop, create a list of type Step
List<Step> steps = new ArrayList();
// your loop on response received from server
for (int i = 0; i < response.body().getRes().getToday().size(); i++) {
if (response.body().getRes().getToday().get(i).getType().equals("penny")) {
StepDynamicEdt stepDynamicEdt = new StepDynamicEdt(response.body().getRes().getToday().get(i).getName());
// add to list
steps.add(stepDynamicEdt);
} else if (response.body().getRes().getToday().get(i).getType().equals("best")) {
StepDynamicTxt stepDynamicTxt = new StepDynamicTxt(response.body().getRes().getToday().get(i).getName());
// add to list
steps.add(stepDynamicTxt);
}
}
// finally create them
stepper.setup(new StepperFormListener() {
#Override
public void onCompletedForm() {
}
#Override
public void onCancelledForm() {
}
}, steps) // pass the list
.allowNonLinearNavigation(false)
.displayCancelButtonInLastStep(false)
.displayBottomNavigation(false)
.confirmationStepTitle("Confirm")
.stepNextButtonText("Continue")
.lastStepNextButtonText("Finish")
.includeConfirmationStep(false)
.init();

It gives me an error it should not since I give it a value? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
My main activity:
public class DiaryActivity extends AppCompatActivity {
private ArrayList<String> allURL = new ArrayList<>();
public void setList(ArrayList<String> list) {
this.allURL = list;
}
private void fireYourAsyncTask() {
new shitson(this).execute();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diary);
fireYourAsyncTask();
}
My other .java:
public class shitson extends AsyncTask<Void, Void, ArrayList<String>> {
ArrayList<String> tmp;
private DiaryActivity activity;
public shitson(DiaryActivity diaryActivity) {
}
protected ArrayList<String> doInBackground(Void... arg0) {
tmp = new ArrayList<>();
HttpHandler sh = new HttpHandler();
String url2 = "https://................";
String jsonStr = sh.makeServiceCall(url2);
if (jsonStr != null) {
try {
JSONArray urlOfURLs = new JSONArray(jsonStr);
for (int i = 0; i < urlOfURLs.length(); i++) {
JSONObject JSONURL = urlOfURLs.getJSONObject(i);
String url = JSONURL.getString("url");
tmp.add(url);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
writeout();
return null;
}
#Override
protected void onPostExecute(ArrayList<String> strings) {
super.onPostExecute(strings);
activity.setList(tmp);
}
public void writeout() {
for (String i : tmp) {
Log.e("-0-0-0-0-0-0-0-", i);
}
}
}
What I want to have the list I made in shitson.java in my DiaryActivity. In the shitson.java the writeout() function writes the right informations in Logcat but at activity.setList(tmp); I get error messages like these:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.petkovics.mango.DiaryActivity.setList(java.util.ArrayList)' on a null object reference
at com.example.petkovics.mango.shitson.onPostExecute(shitson.java:57)
at com.example.petkovics.mango.shitson.onPostExecute(shitson.java:20)
What is non-sense since the writeout() function after I filled up the "tmp" ArrayList, it tells me every single data it has to do. But still in onPostExecute it gets crazy...
You have
private DiaryActivity activity;
which defines an uninitialized DiaryActivity object named activity.
And you have the constructor
public shitson(DiaryActivity diaryActivity) {
}
which takes a DiaryActivity object as argument but does nothing with it, and more importantly the constructor is leaving activity uninitialized (and therefore null).
Then you use activity even though it's a null object!
Your constructor should probably set the activity member to the passed object:
public shitson(DiaryActivity diaryActivity) {
activity = diaryActivity;
}

Trying to update a class variable from within an Android's Response.Listener's `onResponse` method

I'm trying to set a class variable from within this overriden method. I understand that this is executed in another thread. If I output it from there, I get the value. If I output it in a method below, values are null.
How to go about setting this class variable in a correct way?
public class MainActivity extends AppCompatActivity {
private String[] mRestTitles = new String[2];
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject rootObject = response.getJSONObject("_embedded");
JSONArray users = rootObject.getJSONArray("users");
for (int i = 0; i < users.length(); i++) {
JSONObject o = users.getJSONObject(i);
mRestTitles[i] = o.getString("firstName");
Log.d("item", mRestTitles[i]);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("erro", error.toString());
}
}
);
queue.add(request);
public ArrayList<Entry> generateEntryList(){
String[] entryTitles = getResources().getStringArray(R.array.entry_names);
String[] entryDescriptions = getResources().getStringArray(R.array.entry_description);
ArrayList<Entry> entries = new ArrayList<>();
for(int i = 0; i < mRestTitles.length; i++){
// mRestTitles is here null
Log.d("foo", mRestTitles[i]);
entries.add(new Entry(mRestTitles[i], entryDescriptions[i]));
}
return entries;
}
Follow these steps to handle this situation:
1) Create your own interface with parameter as your variable ( That has to be used anywhere)
public interface yourInterface
{
public void updateMyVariable(String variable);
}
2) Implement that interface where ever you want to receive the variable's value.
#override
public void updateMyVariable(String variable)
{
//get the value here
}
3) Invoke the interface from your onResponse Method as soon as you get the variale's value like this.
yourInterface.updateMyVariable( VariableToBeUsed );
Make sure yourInterface object has the reference to the context of the
activity that is implementing/overriding the function.

displaying value, but selecting an id from drop down list

The user types 2 letters in the autocomplete text box
Those 2 letters get saved and used in a web service method in order to
retrieve all users who start with those 2 letters
XML result get returned, and get parsed, and we retrieve the user name+ the id and
save each one in different ArrayList
the result from the first name arraylist get puts in an a dropdown list (the autocomplete one)
The user select an item from the drop list items
--
I need to display the name in the drop down list, however, when the user chooses a name, that user ID should be selected and saved as a String in order to be used for another query.
Question is: How to display the name but select the ID for that name
AutoCompleteTextView assigneeInput;
assigneeInput=(AutoCompleteTextView)
findViewById(id.editassignee);
assigneeInput.addTextChangedListener(new
TextWatcher() {
#Override
public void onTextChanged (CharSequence s,int start, int before, int count){
getContactsForAssignee();
}
#Override
public void beforeTextChanged (CharSequence s,int start, int count, int after){
}
#Override
public void afterTextChanged (Editable s){
}
}
);
//Textwatcher for assignee input -end
}
//Method to get Contacts for the assignee autocomplete - Start
public void getContactsForAssignee() {
//webservice call method
}
//Method to get Contacts for the assignee autocomplete - End
public void receiveResults10(String result10) {
try {
//Dom parsing set up
List<String> valSetOne = new ArrayList<String>();
List<String> valSetTwo = new ArrayList<String>();
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < nodesUDSObjectList.getLength(); i++) {
Element elementUDSObject = (Element) nodesUDSObjectList.item(i);
NodeList nodesAttributeList = elementUDSObject.getElementsByTagName("Attribute");
HashMap<String, String> mapp = new HashMap<String, String>();
for (int iA = 0; iA < nodesAttributeList.getLength(); iA++) {
Element elementAttribute = (Element) nodesAttributeList.item(iA);
//You have attribute(iA)
NodeList AttrNameElementList = (NodeList) elementAttribute.getElementsByTagName("AttrName");
String nameValue = getCharacterDataFromElement((Element) (AttrNameElementList.item(0)));
System.out.println("name" + nameValue);
NodeList AttrValueElementList = (NodeList) elementAttribute.getElementsByTagName("AttrValue");
String valueValue = getCharacterDataFromElement((Element) (AttrValueElementList.item(0)));
if (nameValue.equals("name")) {
valSetOne.add(valueValue);
mapp.put(COMBO_NAME, valueValue);
}
if (nameValue.equals("id")) {
valSetTwo.add(valueValue);
mapp.put(PERSISTENT_ID, valueValue);
}
}
menuItems.add(mapp);
}
AutoCompleteTextView editAssignee;
ArrayAdapter<String> adapter;
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, valSetOne);
editAssignee = (AutoCompleteTextView) findViewById(R.id.editassignee);
editAssignee.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getCharacterDataFromElement(Element e) {
}
//Beginning of method to actually save the ticket executed on click of the "save" button
public void SaveThisIncident(View v) {
AutoCompleteTextView editAssigneeInput = (AutoCompleteTextView) findViewById(R.id.editassignee); //receiving the users input for assignee
String thisIsAssignee = editAssigneeInput.getText().toString();
}
You need to set itemclicklistner for your AutoCompleteTextView editAssignee & use BaseAdapter instead of ArrayAdapter.
Pass ArrayList of your custom object which contain both id & string value to baseadapter.
Custom object can be
public class item{
String id;
String value;
}
Now onClickItem you can get both id & value from your Arraylist

Robospice + Retrofit + ORMLite

I'm using Robospice with Retrofit ans ORMLite modules. Retrofit part working good. I have City model for Retrofit:
City.java:
public class City {
public int city_id;
public String name;
#SuppressWarnings("serial")
public static class List extends ArrayList<City> {
}
}
I'm taking this model from server by GET-request:
MyApi.java
public interface MyAPI {
#GET("/cities")
City.List getCities();
}
This part works fine by calling this method:
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
and listener:
public final class ListCityRequestListener implements RequestListener<City.List> {
#Override
public void onRequestFailure(SpiceException spiceException) {
Toast.makeText(RegisterActivity.this, "failure", Toast.LENGTH_SHORT).show();
}
#Override
public void onRequestSuccess(final City.List result) {
Toast.makeText(RegisterActivity.this, "success", Toast.LENGTH_SHORT).show();
updateCities(result);
}
}
At this time i want to download city list once from server and store this list into sqlitedb by ORMLite module. I've created ORMLite model:
City.java
#DatabaseTable(tableName = "city")
public class City {
public final static String DB_CITY_ID_FIELD_NAME = "id";
public final static String DB_CITY_NAME_FIELD_NAME = "name";
#DatabaseField(canBeNull = false, dataType = DataType.INTEGER, columnName = DB_CITY_ID_FIELD_NAME)
int id;
#DatabaseField(canBeNull = false, dataType = DataType.STRING, columnName = DB_CITY_NAME_FIELD_NAME)
private String name;
public City() {
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("id = ").append(id);
sb.append(", ").append("name = ").append(name);
return sb.toString();
}
}
My RetrofitSpiceService.java looks like this:
public class RetrofitSpiceService extends RetrofitGsonSpiceService {
private final static String BASE_URL = "http://example.com/api/v1";
private final static UserFunctions userFunctions = new UserFunctions();
#Override
public CacheManager createCacheManager(Application application) throws CacheCreationException {
CacheManager cacheManager = new CacheManager();
List< Class< ? >> classCollection = new ArrayList< Class< ? >>();
// add persisted classes to class collection
classCollection.add( City.class );
// init
RoboSpiceDatabaseHelper databaseHelper = new RoboSpiceDatabaseHelper( application, "sample_database.db", 1 );
InDatabaseObjectPersisterFactory inDatabaseObjectPersisterFactory = new InDatabaseObjectPersisterFactory( application, databaseHelper, classCollection );
cacheManager.addPersister( inDatabaseObjectPersisterFactory );
return cacheManager;
}
#Override
protected Builder createRestAdapterBuilder() {
Builder mBuilder = super.createRestAdapterBuilder();
mBuilder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
if (userFunctions.isUserLoggedIn()) {
request.addHeader("Authorization", userFunctions.getToken());
}
}
});
return mBuilder;
}
#Override
public void onCreate() {
super.onCreate();
addRetrofitInterface(MyAPI.class);
}
#Override
protected String getServerUrl() {
return BASE_URL;
}
}
I can't understand how can i store and read data from my City database? How do i need to change RetrofitSpiceService? I want download data by Retrofit and store it to database by ORMLite. My CacheManager is correct, i.e. will work properly? Maybe I misunderstand how the module Robospice-ORMLite works?
Thanks a lot!
When you make execute() call with cache key and duration Robospice will store your response into database.
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
All following requests during one minute will get data from this cache, and then it makes network call. If you want to get data only from cache take a look on getSpiceManager().getFromCache() method. I think it's what you are looking for.

Categories

Resources