the problem that i'm facing right now is;
on my homeactivity i have some outputs from json. but those values does change so i have to keep homeactivity updated.
when i add jsonrequest() in the onRestart()
it does get the latest values when i restart the app, or when i'm switching between activities. BUT everytime that i'm switching between activities it does add more fields. example: in my json file i do have
username: John
homeactivity shows John ; switching between activities, the homeactivity shows; John John etc..
i also have jsonrequest() in the onCreate()
private void jsonrequest() {
request = new JsonArrayRequest(JSON_URL, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSONObject jsonObject = null;
for (int i = 0 ; i < response.length(); i++ ) {
try {
jsonObject = response.getJSONObject(i);
User user = new User();
user.setUsername(jsonObject.getString("username"));
lstUser.add(user);
} catch (JSONException e) {
e.printStackTrace();
}
}
setuprecyclerview(lstUser);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(DashBoardActivity.this);
requestQueue.add(request) ;
}
value in lstUser gets double every time because you are adding new value in lstUser every time, but you are not removing old value from that array.
so before adding User in lstUser, remove old value available in that array. As :
public void onResponse(JSONArray response) {
JSONObject jsonObject = null;
lstUser.clear(); // Here remove old value, so in new list you have only latest values.
for (int i = 0 ; i < response.length(); i++ ) {
try {
jsonObject = response.getJSONObject(i);
User user = new User();
user.setUsername(jsonObject.getString("username"));
lstUser.add(user);
} catch (JSONException e) {
e.printStackTrace();
}
}
setuprecyclerview(lstUser);
}
I'm currently stuck on how I'm going to display my data to my spinner. So basically I am using Websocket to receive data and run it on my UI thread my problem is that there is no list of data showing in my spinner.
Here is my code:
WayPointData = new SubscribedData<>();
final Type WayPointType = new TypeToken<SubscribedData<WayPoint>>() {
}.getType();
/** an ID for the spinner **/
spin = (Spinner) findViewById(R.id.spinner);
final SpinnerAdapter adapter = new ArrayAdapter<String>(Pop.this, android.R.layout.simple_spinner_item);
spin.setAdapter(adapter);
rosbridge = new RosbridgeListener("ws://10.24.204.231:9090");
rosbridge.setOnDataReceivedListener(new RosbridgeMessageListener() {
/**
* a running thread that when the connection is made the data of the topic will serialize and deserialized java objects
* to (and from) JSON.
* #param msg
*/
#Override
public void onDataReceived(final String msg) {
try {
runOnUiThread( new Runnable() {
#Override
public void run() {
try {
WayPointData = new Gson().fromJson(msg,WayPointType);
JSONObject jsonObject = new JSONObject();
JSONArray wayPointJsonArray = jsonObject.getJSONObject("msg").getJSONArray("waypoints");
for (int i = 0; i < wayPointJsonArray.length(); i++) {
JSONObject wayPointJsonObject = wayPointJsonArray.getJSONObject(i);
// Parse name
String name = wayPointJsonObject.getString("name");
WayPoint wayPoint = new WayPoint();
wayPoint.name = name;
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
/** a msg that will display once the data is received **/
Log.d("B9T", String.format("Received data: %s", msg));
} catch (Exception e) {
e.printStackTrace();
}
}
});
spin.setAdapter(adapter);
spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int p, long id) {
WayPoint wayPoint = (WayPoint) parent.getItemAtPosition(p);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Thanks to anyone who can help me!
add array when you initing your adapter:
final SpinnerAdapter adapter = new ArrayAdapter<String>(Pop.this, android.R.layout.simple_spinner_item, yourStringArray);
if you make changes later (will receive list from server) just setup array that you used before with new data and use adapter.notifyDataSetChanged()
Here I can see you don't pass json string to JSONObject that's why your main JSON object is an empty json object.
You should pass the JSON string to the JSONObject parameter like below.
JSONObject jsonObject = new JSONObject(msg); // here you have to add your json string in JSONObject parameter
Hope it helps you.
I am just getting into Android Architecture and have encountered an issue after following this tutorial by mitch:
ViewModel doesn't show any data from the internet- I'm using volley- on first run.
The UI remains blank and only shows data on the views only onChange. i.e A screen rotation/refresh
If I manually set this data, it shows them on first run as required
i.e dataSet.add(new DecodeHouseDetails(1,1,1,"H2345","treutue.jpg","House 1","4345423232312","3224342434232") ); //Add data to the mutatable list
But once I include the network data, it misbehaves.
I have tried checking if my repository could be returning a null list on first run but the toast attached inside the repository shows that the data was well received, only that I dont understand why it wont display until either a change in screen rotation or a refresh
My Repository
public class GetHouseDetailsRepository {
private Context mContext;
private static final String URL_initializeDashboard= CustomFunctions.root_house_admin_url+"initialize_dashboard";
CustomFunctions func= new CustomFunctions();
private static GetHouseDetailsRepository instance;
private ArrayList<DecodeHouseDetails> dataSet= new ArrayList<>();
private JSONObject jsonObject;
public static GetHouseDetailsRepository getInstance(){
if(instance == null){
instance = new GetHouseDetailsRepository();
}
return instance;
}
//Make a mutable list of the data that we will be getting from the database
public MutableLiveData<List<DecodeHouseDetails>> getHouseDetails(Context mContext){
this.mContext=mContext;
getDatabaseHouseDetails();
MutableLiveData<List<DecodeHouseDetails>> myData= new MutableLiveData<>();
if(dataSet ==null){
getDatabaseHouseDetails();
}
myData.setValue(dataSet);
return myData;
}
//Method to actually get the data from the database
public void getDatabaseHouseDetails(){
//dataSet.add(new DecodeHouseDetails(1,1,1,"H2345","treutue.jpg","Keja Mkononi","1","A nice house","Water,electrivit","Other amenities","5","1","Embu","1","1","1","1","4345423232312","3224342434232") ); //Add data to the mutatable list
jsonObject= new JSONObject();
try {
jsonObject.put("me",""+func.getSharedUserID(mContext) );//Logged in user
} catch (JSONException e) {
Log.e("JSONObject Here", e.toString());
}
VolleyNetworkRequestInterfaceSingleton.getResponse(mContext,Request.Method.GET, URL_initializeDashboard, jsonObject,new VolleyNetworkRequestInterfaceSingleton.VolleyCallback(){
#Override
public void onSuccessResponse(String response) {
if(response!=null) {
try {
JSONObject json = new JSONObject(response);
//Successfully fetched
String sarray = json.getString("house_details");
Toast.makeText(mContext, sarray, Toast.LENGTH_SHORT).show();
JSONArray jsonArray = new JSONArray(sarray);
//Clear list to refresh list in every selection
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json_list = jsonArray.getJSONObject(i);
DecodeHouseDetails houses_array = new DecodeHouseDetails(
json_list.getInt("active_identifier"),
json_list.getInt("house_id"),
json_list.getInt("house_status"),
json_list.getString("house_number"),
json_list.getString("house_cover"),
json_list.getString("house_name"),
json_list.getString("longitude"),
json_list.getString("latitude")
);
dataSet.add(houses_array);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
}
My ViewModel
public class GetHouseDetailsViewModel extends AndroidViewModel {
//The data we fetch from asynchronously
private MutableLiveData<List<DecodeHouseDetails>> mHouseDetailsList;
private GetHouseDetailsRepository mHouseDetailsRepository;
public GetHouseDetailsViewModel(#NonNull Application application) {
super(application);
}
public void init(){
if(mHouseDetailsList != null){
mHouseDetailsList= new MutableLiveData<>();
}
mHouseDetailsRepository = GetHouseDetailsRepository.getInstance(); //Initialize the repository
mHouseDetailsList = mHouseDetailsRepository.getHouseDetails(this.getApplication());
}
public LiveData<List<DecodeHouseDetails>> getHouseInfo() {
if(mHouseDetailsList == null){
mHouseDetailsList = new MutableLiveData<>();
}
return mHouseDetailsList;
}
}
My View - Fragment
public class AdmManageHouses extends Fragment {
private ProgressBar progressloader,progressloader_large;
SwipeRefreshLayout refreshLayout;
private TextView house_number_text,house_title_text,house_name_text;
private GetHouseDetailsViewModel mHouseDetailsViewModel;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1_manage_houses, container, false);
mHouseDetailsViewModel = ViewModelProviders.of(getActivity()).get(GetHouseDetailsViewModel.class);
//Innitialize objects
house_title_text= rootView.findViewById(R.id.house_title);
house_number_text= rootView.findViewById(R.id.house_number);
house_name_text= rootView.findViewById(R.id.house_name);
//Initialize the view model
mHouseDetailsViewModel.init();
mHouseDetailsViewModel.getHouseInfo().observe(getViewLifecycleOwner(), new Observer<List<DecodeHouseDetails>>() {
#Override
public void onChanged(List<DecodeHouseDetails> decodeHouseDetails) {
for(int i=0; i<decodeHouseDetails.size(); i++) {
house_number_text.setText(String.valueOf(decodeHouseDetails.get(i).getHouse_number()));
house_title_text.setText(decodeHouseDetails.get(i).getHouse_name());
house_name_text.setText(decodeHouseDetails.get(i).getHouse_name());
}
}
});
//Refresh on swipe
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
initializeDashboard();
refreshLayout.setRefreshing(false);
}
});
initializeDashboard();
return rootView;
}
private void initializeDashboard() {
for(int i=0; i<mHouseDetailsViewModel.getHouseInfo().getValue().size(); i++) {
house_number_text.setText(String.valueOf(mHouseDetailsViewModel.getHouseInfo().getValue().get(i).getHouse_number()));
house_title_text.setText(mHouseDetailsViewModel.getHouseInfo().getValue().get(i).getHouse_name());
house_name_text.setText(mHouseDetailsViewModel.getHouseInfo().getValue().get(i).getHouse_name());
}
}
}
After thorough checking of the viewmodel, I discovered that problem was in the repository and not the viewModel. I was not calling setValue() properly.
This made the first run - when the list is null - fail to populate the UI until onChange.
I made the following changes to the repository
i.e
Declare myData variable
Private MutableLiveData<List<DecodeHouseDetails>> myData= new MutableLiveData<>();
//Make a mutable list of the data that we will be getting from the database
public MutableLiveData<List<DecodeHouseDetails>> getHouseDetails(Context mContext){
this.mContext=mContext;
getDatabaseHouseDetails();
return myData;
}
//Method to actually get the data from the database
public void getDatabaseHouseDetails(){
//dataSet.add(new DecodeHouseDetails(1,1,1,"H2345","treutue.jpg","Keja Mkononi","1","A nice house","Water,electrivit","Other amenities","5","1","Embu","1","1","1","1","4345423232312","3224342434232") ); //Add data to the mutatable list
jsonObject= new JSONObject();
try {
jsonObject.put("me",""+func.getSharedUserID(mContext) );//Logged in user
} catch (JSONException e) {
Log.e("JSONObject Here", e.toString());
}
VolleyNetworkRequestInterfaceSingleton.getResponse(mContext,Request.Method.GET, URL_initializeDashboard, jsonObject,new VolleyNetworkRequestInterfaceSingleton.VolleyCallback(){
#Override
public void onSuccessResponse(String response) {
if(response!=null) {
try {
JSONObject json = new JSONObject(response);
//Successfully fetched
String sarray = json.getString("house_details");
Toast.makeText(mContext, sarray, Toast.LENGTH_SHORT).show();
JSONArray jsonArray = new JSONArray(sarray);
//Clear list to refresh list in every selection
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json_list = jsonArray.getJSONObject(i);
DecodeHouseDetails houses_array = new DecodeHouseDetails(
json_list.getInt("active_identifier"),
json_list.getInt("house_id"),
json_list.getInt("house_status"),
json_list.getString("house_number"),
json_list.getString("house_cover"),
json_list.getString("house_name"),
json_list.getString("longitude"),
json_list.getString("latitude")
);
dataSet.add(houses_array);
}
myData.setValue(dataSet);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
I am using a LayoutInflater to add dynamic views every time I press the button function. I am trying to add a tag/id to the view so that I can identify each element.
I have tried setTag as well as setId but always seem to end up not being able to find the element
public void onAddField(View v) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.field, null);
rowView.setTag(a);
//rowView.setId(a);
getdata2();
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount() - 1);
Log.d(String.valueOf(parentLinearLayout.getChildAt(a).getId()), "onAddField: " + type2_workout_mySpinner.findViewWithTag(a).);
getdata2();
a = a +1;
}
private void getdata2() {
StringRequest stringRequest = new StringRequest("http://.../getDataCategories.php",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
j = new JSONObject(response);
result = j.getJSONArray(JSON_ARRAY);
catdetails(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void catdetails(JSONArray j) {
for (int i = 0; i < j.length(); i++) {
try {
JSONObject json = j.getJSONObject(i);
arrayList2.add(json.getString(CategoryType_idArray));
} catch (JSONException e) {
e.printStackTrace();
}
}
type2_workout_mySpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, arrayList2));
}
I would like to be able to use a getter class to get the values of each element that I have added for example the value of multiple spinner values selected
i want to make a condition when i call the json and make it to 'you cannot have the same thing' in the json value when you want to add more data to database.
this is my code
String nim2, ruang2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_kelas);
nim = (EditText) findViewById(R.id.editNim);
ruang = (EditText) findViewById(R.id.ruangPinjam);
new daftarMahasiswa().execute();
}
public void nextButton (View view) {
nim2 = nim.getText().toString();
ruang2 = ruang.getText().toString();
if (ruang2.equals(ruangan)) {
Toast.makeText(KelasActivity.this, "this room has already borrow",Toast.LENGTH_LONG).show();
ruang.setError("you cannot borrow the room again");
}else if (nim2.equals(nimMahasiswa)){
Toast.makeText(KelasActivity.this, "this NIM has borrow the room",Toast.LENGTH_LONG).show();
nim.setError("you cannot borrow it again");
}
class daftarMahasiswa extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(KelasActivity.this);
pDialog.setMessage("Loading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
String link_url = "http://192.168.43.54/datapeminjamankelas/read_mahasiswa.php";
JSONParser jParser = new JSONParser();
JSONObject json = null;
try {
json = jParser.AmbilJson(link_url);
} catch (JSONException e) {
e.printStackTrace();
}
try {
str_json = json.getJSONArray("data");
for (int i = 0; i < str_json.length(); i++) {
JSONObject ar = str_json.getJSONObject(i);
ruangan = ar.getString("ruang").trim();
nimMahasiswa = ar.getString("nim").trim();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
pDialog.dismiss();
}
}
and this is my json
{
"data": [
{
"nim": "103452",
"ruang": "2702"
},
{
"nim": "102341",
"ruang": "2504"
},
{
"nim": "103421",
"ruang": "1101"
}
]
}
what i want to make is the 'nim' and the 'ruang' from json cannot be add again with the same value. it works honestly but only when the data just have 1, when it have more it dont work anymore. please help what can i put to make it right
You can add 'nim' and 'ruang' values in separate List and from there, you can check whether the entered value is already present or not.
List<String> nimList = new ArrayList<>();
List<String> ruangList = new ArrayList<>();
for (int i = 0; i < str_json.length(); i++) {
JSONObject ar = str_json.getJSONObject(i);
ruangan = ar.getString("ruang").trim();
nimMahasiswa = ar.getString("nim").trim();
nimList.add(nimMahasiswa);
ruangList.add(ruangan);
}
You can check like below:
nim2 = nim.getText().toString();
ruang2 = ruang.getText().toString();
if (ruangList.contains(ruang2)) {
Toast.makeText(KelasActivity.this, "this room has already borrow",Toast.LENGTH_LONG).show();
ruang.setError("you cannot borrow the room again");
}else if (nimList.contains(nim2)){
Toast.makeText(KelasActivity.this, "this NIM has borrow the room",Toast.LENGTH_LONG).show();
nim.setError("you cannot borrow it again");
}
Better you could have a pojo class and override equals method like below
public class MyData {
private String myNim;
private String myRuang;
//setter & getters here
#Override
public boolean equals(Object obj) {
if(obj instanceOf MyData)
{
MyData myData = (MyData) obj;
return myData.getMyNim().equals(this.myNim)&&myData.getMyRuang().equals(this.myRuang);
}
return false;
}
}
and now you can check the element exist or not by using below code.
try {
str_json = json.getJSONArray("data");
List<MyData> myDataList = new ArrayList<MyData>();
for (int i = 0; i < str_json.length(); i++) {
JSONObject ar = str_json.getJSONObject(i);
ruangan = ar.getString("ruang").trim();
nimMahasiswa = ar.getString("nim").trim();
MyData myData = new MyData();
myData.setMyNim(nimMahasiswa);
myData.setMyRuang(ruangan);
if(myDataList.contains(myData))
//use your logic here to show error 'you cannot have the same thing'
else
myDataList.add(myData);
}
} catch (JSONException e) {
e.printStackTrace();
}
now you can use the myDataList which is having unique elements.