Hi i have an array list which is defined in the beginning of the class and i try too put objects inside it so that i can use it for a custom arrayAdapter for a listview but when i want to use it seems to be empty outside the response Listener i tested it with two Toasts forst one runs with no problem second one throws IndexOutOfBoundsException here's my code i have put comments beside those two Toasts they are in getUserGamesInfo function (sry for the mess that has happened to the code when i pasted it here that happened):
public class account_games_info extends Fragment {
HashMap<String, String> info = new HashMap<>();
String Playerscores, Rivalscore;
String[] array = null;
ListView listView;
ArrayList<gameHistory_object> scoreList=new ArrayList<gameHistory_object>;//*************
gameHistory_object gameHistory_object;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
get_user_games_ids();//a functio that calls getUserGamesInfo but i didnt bring it here
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View games_info = inflater.inflate(R.layout.fragment_account_games_info, container, false);
listView = (ListView) games_info.findViewById(R.id.listView);
return games_info;
}
private void getUserGamesInfo(String gameID) {
final String MY_PREFS_NAME = "username and password";
SharedPreferences prefs = getActivity().getSharedPreferences(MY_PREFS_NAME,
MODE_PRIVATE);
final String id = prefs.getString("userID", null);
info.put("action", "sendGameInformation");
info.put("userID", id);
info.put("gameID", gameID);
JSONObject jsonObject = new JSONObject(info);
final JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,
url, jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
gameHistory_object = new gameHistory_object();
if (id.equals(response.getString("playerOneID"))) {
Playerscores = response.getString("playerOneTotalScore");
Rivalscore = response.getString("playerTwoTotalScore");
gameHistory_object.setRivalUsername(response.getString("playerTwoUsername"));
gameHistory_object.setPlayerScore(Playerscores);
gameHistory_object.setRivalScore(Rivalscore);
} else {
Playerscores = response.getString("playerTwoTotalScore");
Rivalscore = response.getString("playerTwoTotalScore");
gameHistory_object.setRivalUsername(response.getString("playerOneUsername"));
gameHistory_object.setPlayerScore(Playerscores);
gameHistory_object.setRivalScore(Rivalscore);
}
scoreList.add(gameHistory_object);
//first toast which runs with no problem
Toast.makeText(getActivity(),"inside $$$"+scoreList.get(0).getRivalUsername(),Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
if (Playerscores.equals("")) {
playerScore_view.setText("");
} else {
playerScore_view.setText(Playerscores);
rivalScore_view.setText(Rivalscore);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//second toast with outofboundexecption
Toast.makeText(getActivity(),"outside
$$$"+scoreList.get(0).getRivalUsername(),Toast.LENGTH_SHORT).show();
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
}
You never initialize your scoreList :
ArrayList<gameHistory_object> scoreList;
should be
ArrayList<gameHistory_object> scoreList = new ArrayList();
You access the 0th item of your scoreList before it's been put there. The JsonObjectRequest you start is asynchronous. Your code will start the asynchronous request, then continue to the part where you try to make your toast, but the request has not yet ended (the onResponse part), thus your list is empty.
Your arraylist is not initialized any where in your code hence the IndexOutOfBoundsException.
Do this in your variable declaration:
ArrayList<gameHistory_object> scoreList = new ArrayList <>();
Related
So, I have this assignment at school where I have to make in Android Studio an app that manages daily tasks,basically a calendar, but the activities are saved in a server with JSON format. The problem is that I have a list of all activities in a day in a RecyclerView and I have to have a button for each activity that allows me to delete it from the server and I have no idea how can I do that, I mean, when I delete an activity i have to do it with its ID.
I currently have an app that works but i have to add that functionality, i have an Activity that has a recyclerView and shows the name of the task, the start and finish time and a button.I don't know if I can put the task ID in a hidden field so I can use that or is there a better way to do it.
I'm new with Android programming, so its kinda confusing.
This is the code that I use to get the JSON data.
public class dayActivities extends AppCompatActivity {
private RecyclerView mRecyclerView;
private JsonManager json;
ArrayList<Tarea> list;
RequestQueue requestQueue;
String url="http://186.16.12.200:3000/agenda1";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_day_activities);
Bundle b = getIntent().getExtras();
String date = b.getString("fecha");
setTitle(getDate(date));
requestQueue= Volley.newRequestQueue(getApplicationContext());;
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
this.getData(date);
}
public void getData(String date){
list=new ArrayList<Tarea>();
JsonArrayRequest arrReq = new JsonArrayRequest(Request.Method.GET, url + "?fecha=" + date,null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
if (response.length() > 0) {
// The user does have repos, so let's loop through them all.
for (int i = 0; i < response.length(); i++) {
try {
// For each repo, add a new line to our repo list.
JSONObject jsonObj = response.getJSONObject(i);
Integer id = (Integer) jsonObj.get("id");
String actividad = jsonObj.get("actividad").toString();
String fecha = jsonObj.get("fecha").toString();
String inicio = jsonObj.get("horaInicio").toString();
String fin = jsonObj.get("horaFin").toString();
list.add(new Tarea(id,actividad,fecha,inicio,fin));
} catch (JSONException e) {
// If there is an error then output this to the logs.
Log.e("Volley", "Invalid JSON Object.");
}
}
mRecyclerView.setAdapter(new Adaptador(list));
} else {
// The user didn't have any repos.
Log.e("Volley", "Not found");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
error.printStackTrace();
}
});
// Add the request we just defined to our request queue.
// The request queue will automatically handle the request as soon as it can.
requestQueue.add(arrReq);
}
public String getDate(String fecha){
String meses[]={"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto,","Septiembre","Octubre","Noviembre","Diciembre"};
return fecha.substring(6)+" de "+meses[Integer.parseInt(fecha.substring(4,6))-1]+" del "+fecha.substring(0,4);
}
}
So I have been trying to add a suggestion list for my auto-complete text view in android. I have added an onClickListener to it. Whenever onCLick is triggered. I have created an adapter and a data structure called mylist (ArrayList). I can't see any error but at the same time the autocomplete feature is not working. I am pretty sure there is some small glitch I am unable to find. Please let me know where am I going wrong. TIA.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
user_input = findViewById(R.id.autoCompleteTextView1);
Log.i("here", "something");
user_input.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.i("here", "something");
String symbol_auto = String.valueOf(user_input.getText());
String company_auto = "http://us-east-2.elasticbeanstalk.com/autocomplete/"+symbol_auto;
requestQueue = Volley.newRequestQueue(MainActivity.this);
JsonArrayRequest arrayreq = new JsonArrayRequest(company_auto+symbol_auto,
new Response.Listener<JSONArray>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONArray response) {
try {
JSONObject jsonobj = response.getJSONObject(0);
data = jsonobj.getString("Name");
mylist.add(data);
Log.i("here", data);
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,android.R.layout.select_dialog_item, mylist);
user_input.setThreshold(1);
user_input.setAdapter(adapter);
}
// Try and catch are included to handle any errors due to JSON
catch (JSONException e) {
// If an error occurs, this prints the error to the log
e.printStackTrace();
}
}
},
// The final parameter overrides the method onErrorResponse() and passes VolleyError
//as a parameter
new Response.ErrorListener() {
#Override
// Handles errors that occur due to Volley
public void onErrorResponse(VolleyError error) {
Log.e("Volley", "Error");
}
}
);
// Adds the JSON array request "arrayreq" to the request queue
requestQueue.add(arrayreq);
}
});
}
I have tried adding elements to myList manually and it works like charm but the dropdown list just doesnt appear once I try adding it after querying to my back-end. My back-end is working fine. I have verified.
You have to iterate over your elements and add each one to your list, then set the adapter.
new Response.Listener<JSONArray>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONArray response) {
try {
mylist = new ArrayList();
for (int i = 0; i< response.length(); i++){
JSONObject jsonobj = response.getJSONObject(i);
String value = jsonobj.getString("Name");
mylist.add(value);
Log.i("here", value);
}
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,android.R.layout.select_dialog_item, mylist);
user_input.setThreshold(1);
user_input.setAdapter(adapter);
}
// Try and catch are included to handle any errors due to JSON
catch (JSONException e) {
// If an error occurs, this prints the error to the log
e.printStackTrace();
}
}
},
UPDATE - use OnClickListener to fire the event
user_input.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("here", "something");
String symbol_auto = String.valueOf(user_input.getText());
String company_auto = "http://us-east-2.elasticbeanstalk.com/autocomplete/"+symbol_auto;
requestQueue = Volley.newRequestQueue(MainActivity.this);
JsonArrayRequest arrayreq = new JsonArrayRequest(company_auto+symbol_auto,
new Response.Listener<JSONArray>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONArray response) {
try {
mylist = new ArrayList();
for (int i = 0; i < response.length(); i++){
JSONObject jsonobj = response.getJSONObject(i);
String value = jsonobj.getString("Name");
mylist.add(value);
Log.i("here", value);
}
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,android.R.layout.select_dialog_item, mylist);
user_input.setThreshold(1);
user_input.setAdapter(adapter);
}
// Try and catch are included to handle any errors due to JSON
catch (JSONException e) {
// If an error occurs, this prints the error to the log
e.printStackTrace();
}
}
},
// The final parameter overrides the method onErrorResponse() and passes VolleyError
//as a parameter
new Response.ErrorListener() {
#Override
// Handles errors that occur due to Volley
public void onErrorResponse(VolleyError error) {
Log.e("Volley", "Error");
}
}
);
// Adds the JSON array request "arrayreq" to the request queue
requestQueue.add(arrayreq);
}
});
I am working on a Bitcoin dashboard for Android. The following fragment uses the entered wallet address to display the balance in BTC. When an address is entered, it will add to the listview. When an item in the listview is selected, it will set the edittext to that address.
It is not yet complete, but for now it is throwing an error with the message, "The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread."
I currently have two example addresses in place for testing. If I select one then the other then the first again etc. it works fine. The error appears when I select one, press the button, then select the other.
public class WalletFragment extends Fragment {
ArrayList<String> savedWallets;
ArrayAdapter<String> listAdapter;
String newWalletAddress, jsonString, address, balance;
JSONObject jsonObj, data;
Double balanceDouble;
DecimalFormat df = new DecimalFormat("#.####");
private WalletListener listener;
public interface WalletListener {
void onCreateWallet(String newWalletAddress);
}
public WalletFragment() {
// Required empty public constructor
}
public static WalletFragment newInstance(ArrayList<String> wallets) {
WalletFragment fragment = new WalletFragment();
Bundle args = new Bundle();
args.putStringArrayList("savedWallets", wallets);
fragment.setArguments(args);
return fragment;
}
public static WalletFragment newInstance(ArrayList<String> wallets, String json) {
WalletFragment fragment = new WalletFragment();
Bundle args = new Bundle();
args.putStringArrayList("savedWallets", wallets);
args.putString("jsonString", json);
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof WalletListener) {
listener = (WalletListener) context;
}
else {
throw new ClassCastException(context.toString()
+ " must implement MyListFragment.OnItemSelectedListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_wallet, container, false);
ListView lv = (ListView) v.findViewById(R.id.walletListView);
df.setRoundingMode(RoundingMode.CEILING);
final EditText walletAddressEditText = (EditText) v.findViewById(R.id.walletAddressEditText);
TextView addressTV = (TextView) v.findViewById(R.id.walletAddresstextView);
TextView balanceTV = (TextView) v.findViewById(R.id.walletBalanceTextView);
savedWallets = getArguments().getStringArrayList("savedWallets");
if (savedWallets == null) {
savedWallets = new ArrayList<>();
}
savedWallets.add("198aMn6ZYAczwrE5NvNTUMyJ5qkfy4g3Hi");
savedWallets.add("1L8meqhMTRpxasdGt8DHSJfscxgHHzvPgk");
// TODO remove test addresses
jsonString = getArguments().getString("jsonString");
if (jsonString != null) {
try {
jsonString = getArguments().getString("jsonString");
jsonObj = new JSONObject(jsonString);
data = new JSONObject(jsonObj.getString("data"));
balance = data.getString("balance");
balanceDouble = Double.parseDouble(balance);
address = data.getString("address");
String walletAddressText = getResources().getString(R.string.wallet_address, address);
addressTV.setText(walletAddressText);
String walletBalanceText = getResources().getString(R.string.wallet_balance, df.format(balanceDouble));
balanceTV.setText(walletBalanceText);
// TODO add viewing for other wallet data at some point
} catch (Exception e) {
Log.d("TickerException", e.toString());
}
}
listAdapter = new ArrayAdapter<>(getActivity(), R.layout.main_list_rows, savedWallets);
lv.setAdapter(listAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
String address = savedWallets.get(position);
Log.d("wallet", "Selected: " + address);
walletAddressEditText.setText(address);
}
});
Button button = (Button) v.findViewById(R.id.createWalletButton);
View.OnClickListener ocl = new View.OnClickListener() {
#Override
public void onClick(View view) {
newWalletAddress = walletAddressEditText.getText().toString();
if (walletAddressEntryStructuralValidation(newWalletAddress)) {
if (newWalletAddress != null) {
listener.onCreateWallet(newWalletAddress);
}
else {
Toast.makeText(getActivity(), "newWalletAddress is null", Toast.LENGTH_SHORT).show();
}
}
else {
Toast.makeText(getActivity(), "Please enter a valid wallet address (length is currently " + newWalletAddress.length() + ").", Toast.LENGTH_SHORT).show();
}
}
};
// TODO check if wallet is already on list
button.setOnClickListener(ocl);
return v;
}
public boolean walletAddressEntryStructuralValidation(String address) {
return ((address.length() > 25) &&
(address.length() < 36) && (
(address.substring(0,1).equals("1") ||
(address.substring(0,1).equals("3")))));
}
// Wallet addresses are 26-35 alphanumeric characters and begin with 1 or 3
}
I believe this is all the relevant code but I will be closely watching this thread if anyone needs to request additional source.
That message means that the contents of the adapter (the order of items you see in getItem) changed but notifyDataSetChanged or similar function wasn't called. When changing the items in your adapter contents (which in this case is the savedWallets array list) you must call one of those functions.
Note: If you're adding several objects at once, you only need to call it once after all are added/removed. If you're mutating an object but not adding/removing it, you do not need to call it, but calling it may be the easiest way of doing a redraw.
I've a RecyclerView, Async Task, Json File .
What i want :
Get the Json and add an item for every loop .
My problem :
I'm getting the json, and looping, But the "List.add(Item)" isn't adding any line, So the recycler is empty .
Code :
Adapter RcAdapter;
public static List<CatItem> Items;
String DATA_URL;
#SuppressLint("InflateParams")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinLayout = (LinearLayout) inflater.inflate(R.layout.cat_recycler,
container, false);
setHasOptionsMenu(true);
DATA_URL = this.getArguments().getString(MainActivity.DATA);
initListViews();
return LinLayout;
}
private void initListViews() {
List<CatItem> rowListItem = getAllItemList();
LinearLayoutManager gridLayout = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
RecyclerView RcView = (RecyclerView) LinLayout.findViewById(R.id.cat_rv);
RcView.setHasFixedSize(true);
RcView.setLayoutManager(gridLayout);
RcAdapter = new Adapter(getActivity(), rowListItem);
RcView.setAdapter(RcAdapter);
}
private List<CatItem> getAllItemList() {
Items = new ArrayList<>();
new GetDevices().execute(DATA_URL);
return Items;
}
class GetDevices extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading Devices, Please Wait..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... params) {
return JsonUtils.getJSONString(params[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(pDialog != null)
pDialog.dismiss();
if(result == null){
Toast.makeText(getActivity(),"Failed To Fetch Data, Please Refresh",Toast.LENGTH_LONG).show();
} else {
try {
JSONObject MainJSON = new JSONObject(result);
JSONArray DevicesArrays = MainJSON.getJSONArray("roms_center");
for (int i = 0; i < DevicesArrays.length() ; i++){
CatItem Item = new CatItem();
JSONObject first = DevicesArrays.getJSONObject(i);
Log.LogInfo("I'm In Position " + i);
Item.setDevice_Name(first.getString("device_name"));
Item.setTotal_Downloads(first.getInt("roms_count"));
Item.setDevice_ID(first.getInt("device_id"));
Items.add(Item);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
What's the problem ?
Also, In my holder i've implemented OnClick, and i want to get something from the pressed position, I'm using the following way :
Main.Items.get(getLayoutPosition()).getDevice_ID()
As you can see, I'm getting the static List, Any better way to achieve this ?
The program flow between these two lines is not what you think it is.
new GetDevices().execute(DATA_URL);
return Items;
GetDevices is an AsyncTask, which means it will run asynchronously.
The return statement in the next line will not wait for the async task to finish, and it returns null because async task takes time to finish.
After you've added an item to your list you have to tell your adapter about it. So you could do it in two ways:
RcAdapter.notifyItemInserted(Items.size() - 1);
or
RcAdapter.notifyDataChanged();
I have an activity that displays a list of activities (name, picture, brief description), and where those information are derived from JSON data. I am trying to figure out how I could add a criteria where only the list of activities that falls within lets say 100km would be shown.
I was thinking of adding the following to my JSON data
"location_code":"(49, -123)", where 49 represents latitude and -123 longitude, and what would happen is that it would evaluate the location_code of the activity in respect to the current location of the user and would only populate activities that falls within that range.
Below is my current code:
public class CultureEventsActivity extends Activity{
private static final String URL_WEB_SERVICE = "http://dooba.elasticbeanstalk.com/analytics/culture.php";
private GridView gv;
private ArrayList<Events_List> container;
private ArrayList<Events_List> items;
public Uri list_item_bac;
public String list_item_name;
public String list_item_description;
public String list_item_location;
public String single_list_item_description;
public String list_item_price;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.events_list_layout);
gv = (GridView) findViewById(R.id.gridview);
container = new ArrayList<Events_List>();
//download JSON
listDownload();
GridView s = (GridView) findViewById(R.id.gridview);
s.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(CultureEventsActivity.this,CultureEventsSingleItemActivity.class);
intent.putExtra("list_item_name", container.get(position).getList_item_title());
intent.putExtra("list_item_price", container.get(position).getList_item_price());
intent.putExtra("list_item_location", container.get(position).getList_item_location());
intent.putExtra("single_list_item_description", container.get(position).getSingle_list_item_description());
intent.putExtra("list_item_bac", container.get(position).getList_item_bac().toString());
intent.putExtra("list_item_purchase_code", container.get(position).getList_item_purchase_code());
startActivity(intent); //start Activity
}
});
}
public void listDownload(){
RequestQueue volley = Volley.newRequestQueue(this);
JsonObjectRequest json = new JsonObjectRequest(Method.GET, URL_WEB_SERVICE, null, ResponseListener(), ErrorListener());
volley.add(json);
}
private Response.Listener<JSONObject> ResponseListener() {
return new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//your JSON Array
JSONArray array = response.getJSONArray("list_item");
for(int i = 0; i < array.length(); i++){
container.add(convertirAnuncio(array.getJSONObject(i)));
}
} catch (JSONException e) {
e.printStackTrace();
}
gv.setAdapter(new AdapterEvents(getApplicationContext(),container));
}
};
};
private Response.ErrorListener ErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) { }
};
}
//object JSON
private final Events_List convertirAnuncio(JSONObject obj) throws JSONException {
long id = obj.getLong("id"); //id
String list_item_name = obj.getString("list_item_name");
String list_item_location = obj.getString("list_item_location");
String list_item_description = obj.getString("list_item_description");
String list_item_price = obj.getString("list_item_price");
String list_item_purchase_code = obj.getString("list_item_purchase_code");
String single_list_item_description = obj.getString("single_list_item_description");
Uri uri = Uri.parse(obj.getString("list_item_bac"));
return new Events_List(id, list_item_location, single_list_item_description,list_item_name,list_item_description,list_item_price,list_item_purchase_code, uri, uri);
}
}
As of now the code populates all activities, and does not filter by search zone. It would also be nice if I could include a constant like private String SEARCH_DISTANCE = 100KM;
PS. I am also using Parse, where the current user is derived from Parse, but I am not sure if that's relevant.
Any help would be greatly appreciated as I have been trying to figure this out since a while.
If you require any further clarification, let me know.