Create Dynamic alert dialog box with multiple options to select - java

When user clicks on location element then app populate alert dialog to select location , this locations are coming from php server open .Below is the code i have used.
Declaration
final String locations[] = new String[100];
final String locations_id[] = new String[100];
onPostExecute
jObj = new JSONObject(json);
JSONArray locations_resp = jObj.getJSONArray("Locations");
JSONArray manufacturer_resp = jObj.getJSONArray("Manufacturers");
for(int i=0;i<locations_resp.length();i++)
{
JSONObject c = locations_resp.getJSONObject(i);
int id = c.getInt("id");
String name = c.getString("title");
locations[i]=name;
locations_id[i]=id+"";
//Log.d("Locations","Id ="+id+" name = "+name );
}
onclick Event
location_ele.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Select Location");
builder.setItems(locations, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// the user clicked on colors[which]
location_ele.setText(locations[which]);
location=locations_id[which].toString();
}
});
builder.show();
}
});
Screen shot
Observe the screen. locations are coming randomly along with some null values there are only 4 locations coming from API.Please suggest me procedure how to create this locations list dynamically with out Null value please notice i have created Locations as fixed size array.

In your post execute you need a condition when looping on locations_resp that checks when a location is null or empty so you won't add it to your location array.
I would suggest to work with List instead of array so your listview matches the size of the datasource (for instance show a list of 2 locations instead a list of 10 locations where 8 are empty).
List<String> locations = new ArrayList<String>();
List<String> locationsId = new ArrayList<String>();
for (JSONObject c : locations_resp)
{
int id = c.getInt("id");
String name = c.getString("title");
if(name != null && name.length > 0)
{
locations.add(name);
locationsId.add(String.valueOf(id));
}
}
I'll also suggest to have a local Location representation instend of having 2 array so you can do something like :
List<Location> locations = new ArrayList<Location>();
for (JSONObject c : locations_resp)
{
int id = c.getInt("id");
String name = c.getString("title");
if(name != null && name.length > 0)
{
locations.add(new Location(name, id));
}
}
and work with the Location object.

Related

List DataModel reads just the last element

I have a database created with location updates and in the database there is a bunch of locations x and y. and in the second method readFirestore() reads the location data and compares the favorite locations which came from sqlite database and if the favorite location is near the data from firestore it writes the campaign name which is on the same location to another database. But when I want to compare the favorite location in the firestore methot, there is just the last item of the database. I looked with the Log.
Code 1:
public List<DataModel> listFavoriteLocation(){
db = new DatabaseHelper(this);
SQLiteDatabase mydb = db.getWritableDatabase();
List<DataModel> data=new ArrayList<>();
Cursor csr = mydb.rawQuery("select * from "+TABLE+" ;",null);
StringBuffer stringBuffer = new StringBuffer();
DataModel dataModel = null;
while (csr.moveToNext()) {
dataModel= new DataModel();
String FAVCurrentLocationLAT = csr.getString(csr.getColumnIndexOrThrow("FAVCurrentLocationLAT"));
String FAVCurrentLocationLONG = csr.getString(csr.getColumnIndexOrThrow("FAVCurrentLocationLONG"));
dataModel.setFAVCurrentLocationLAT(FAVCurrentLocationLAT);
dataModel.setFAVCurrentLocationLONG(FAVCurrentLocationLONG);
stringBuffer.append(dataModel);
data.add(dataModel);
}
for (DataModel mo:data ) {
this.List_FAVCurrentLocationLAT = mo.getFAVCurrentLocationLAT();
this.List_FAVCurrentLocationLONG = mo.getFAVCurrentLocationLONG();
Log.i("helloLAT",""+List_FAVCurrentLocationLAT); //OK
Log.i("helloLONG",""+List_FAVCurrentLocationLONG); //OK
// This section writes the favorite locations seperately to the log.
}
return data;
}
Code 2:
public void readFirestore() {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("campaigns")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
private String FSname,FScityLAT,FScityLONG,FScampaignStartDate,FScampaignEndDate;
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful() && task.getResult() != null) {
for (QueryDocumentSnapshot document : task.getResult()) {
String name = document.getString("name");
String cityLAT = document.getString("cityLAT");
String cityLONG = document.getString("cityLONG");
String campaignStartDate = document.getString("campaignStartDate");
String campaignEndDate = document.getString("campaignEndDate");
this.FSname = name;
this.FScityLAT = cityLAT;
this.FScityLONG = cityLONG;
this.FScampaignStartDate = campaignStartDate;
this.FScampaignEndDate = campaignEndDate;
listFavoriteLocation();
String FS_FAVCurrentLocationLAT = List_FAVCurrentLocationLAT;
String FS_FAVCurrentLocationLONG = List_FAVCurrentLocationLONG;
Log.i("hellolist",""+List_FAVCurrentLocationLAT); // just writes the last loc item from sqlite
double FS_FAVCurrentLocationLAT_double = Double.parseDouble(FS_FAVCurrentLocationLAT); // Fav Loc DB
double FS_FAVCurrentLocationLONG_double = Double.parseDouble(FS_FAVCurrentLocationLONG); double FScityLAT_double = Double.parseDouble(FScityLAT); // Campaign Loc Firestore LAT
double FScityLONG_double = Double.parseDouble(FScityLONG);
double theta = FScityLONG_double - FS_FAVCurrentLocationLONG_double;
double dist = Math.sin(Math.toRadians(FS_FAVCurrentLocationLAT_double)) * Math.sin(Math.toRadians(FScityLAT_double)) + Math.cos(Math.toRadians(FS_FAVCurrentLocationLAT_double)) * Math.cos(Math.toRadians(FScityLAT_double)) * Math.cos(Math.toRadians(theta));
dist = Math.acos(dist);
dist = Math.toDegrees(dist);
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
if (dist <= 0.5) // 500 meter
{
SQLiteQueryFavCampaign = "INSERT OR REPLACE INTO myTable3(FAVCampaignName, FAVCampaigncampaignStartDate, FAVCampaigncampaignEndDate)" + " VALUES('"+FSname+"','"+FScampaignStartDate+"','"+FScampaignEndDate+"');";
SQLITEDATABASEFavCampaign.execSQL(SQLiteQueryFavCampaign);
Log.i("helloname",""+FSname);
}
}
} else {
}
}
});
Toast.makeText(CampaignActivity.this,"Creating", Toast.LENGTH_SHORT).show();
}
If I understand correctly: the listFavoriteLocation method properly retrieves the data you're expecting from the database. If you take a look at the rest of your code, you'll see that you are iterating over the list of data and overwriting your instance variables with them, one-by-one, until the list has been fully iterated over, meaning you will only preserve the last element in your instance once you've left the method.
So, to be clear, the following block will properly log every element, but only the values of the last element will be preserved in the two instance variables you're using (FAVCurrentLocationLAT and FavCurrentLocationLong):
for (DataModel mo:data ) {
this.List_FAVCurrentLocationLAT = mo.getFAVCurrentLocationLAT();
this.List_FAVCurrentLocationLONG = mo.getFAVCurrentLocationLONG();
Log.i("helloLAT",""+List_FAVCurrentLocationLAT); //OK
Log.i("helloLONG",""+List_FAVCurrentLocationLONG); //OK
// This section writes the favorite locations seperately to the log.
}
What you need to do is use the returned data list being loaded in the listFavoriteLocation method, and then manipulate it in the following code as you wish.
So, for example:
List<DataModel> data = listFavoriteLocation();
for (int i = 0; i < data.size(); i++) {
DataModel dataModel = data.get(i);
log.i("Data model "+i+": "+dataModel);
// Do work on each data model element here
}

Java Android How To Save Multiple CheckBox To String If Checked and Store To SharedPref and Retrieve It As A String

So I have 2 screen one to store the other to retrieve. What I want ultimately is storing the checked checkbox into sharedPref, retrieve it as a STRING and put it inside an ArrayList to shuffle for a random STRING that was SELECTED.
So far I tried many solutions but none worked. I always get the unchecked checkbox as well. I only want checked even if I just select ONE of the checkbox. Any advise would be appreciated.
EDIT: I have solve the problem...at least for now. Look at the UpdateReceive.java to see the solution. But however for other screens I will have 9 Checkboxes and the possibilities are too tedious to do it this way. So are there any better methods out there?
Storing.java
SharedPreferences sharedMode = getSharedPreferences("MySharedMode", Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = sharedMode.edit();
editor.clear();
editor.commit();
if ( cbCool.isChecked() || cbHeat.isChecked()) {
editor.putBoolean("Cool", cbCool.isChecked());
editor.putBoolean("Heat", cbHeat.isChecked());
editor.commit();
}
Receieve.java
SharedPreferences sharedMode = getSharedPreferences("MySharedMode", Context.MODE_PRIVATE);
String heat = String.valueOf(sharedMode.getBoolean("Heat", false));
String cool = String.valueOf(sharedMode.getBoolean("Cool", false));
if (heat != null && cool != null) {
String m_heat = "Heat";
String m_cool = "Cool";
List<String> list = new ArrayList<String>();
list.add(m_heat);
list.add(m_cool);
Collections.shuffle(list);
String randMode = list.get(0);
tvMode.setText(randMode);
}
UpdatedReceive.java
if (heat == "true" && cool != "true") {
tvMode.setText("Heat");
}
else if (heat != "true" && cool == "true") {
tvMode.setText("Cool");
}
else if (heat =="true" && cool == "true") {
String m_heat = "Heat";
String m_cool = "Cool";
List<String> list = new ArrayList<String>();
list.add(m_heat);
list.add(m_cool);
Collections.shuffle(list);
String randMode = list.get(0);
tvMode.setText(randMode);
}

Use string values from an array as string variable to parse json - codenameone

I have a no. of checkboxes (20), what i did is if a user select any checkbox, its name is stored in an array (eg abc array below in code). The name of the string variable that stores the respective json is of the same name as of the checkbox. For eg if Checkbox "a" is clicked, string value "a" is stored in array and there is a string variable named "a" that stores the related json values. What I need is that if i pass the string value stored in array as InputStream is = new ByteArrayInputStream(abc.get(i).getBytes()), it should be used to parse the inputStream for json. But it gives NullPointerException since the string value "a" is not equal to string variable a. How can i solve this problem? I ran out of ideas here. Is there other ways to achieve what i want to do here?
code: String values of the selected checkboxes are stored in an array
String a = "[{\n"
+ "\t\t\t\"title\": \"title1\",\n"
+ "\t\t\t\"describ\": \"describ1\"\n"
+ "}]";
String b = "[{\n"
+ "\"title\": \"title2\",\n"
+ "\"describ\": \"describ2\"\n"
+ "}]";
String c = "[{\n"
+ "\t\t\t\"title\": \"title3\",\n"
+ "\t\t\t\"describ\": \"describ3\"\n"
+ "}]";
//and all jsons required are there
ArrayList<String> abc;
#Override
protected void beforeTestForApp(Form f) {
f.setTitle("abc");
abc = new ArrayList<>();
//I have stored "a" & "b" in the abc array here for simplicity, but it is dynamic,
//ie. if the user select checkbox c, c will be stored in abc array and so on
abc.add("a");
abc.add("b");
Button bb = new Button("go");
bb.addActionListener((e) -> {
showForm("TestForAppResult", null);
});
f.add(bb);
}
Form for json parser and displaying the values:
#Override
protected void beforeTestForAppResult(Form f) {
f.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
InputStream is;
for (int i = 0; i < abc.size(); i++) {
Label heading = new Label(abc.get(i));
f.add(heading);
//this gives error since abc.get(i) gives string value, not string variable
is = new ByteArrayInputStream(abc.get(i).getBytes());
showDetails(is, f);
}
//if i do this instead of for loop jst above, i can get the result but since what value'll be stored in an array is not known,it is not possible
//is = new ByteArrayInputStream(a.getBytes());
//showDetails(is, f);
//is = new ByteArrayInputStream(b.getBytes());
//showDetails(is, f);
}
private void showDetails(InputStream is, Form f) {
JSONParser p = new JSONParser();
Hashtable<String, Object> test;
try {
test = p.parse(new InputStreamReader(is));
Vector aVector = (Vector) test.get("root");
for (int j = 0; j < aVector.size(); j++) {
Hashtable hm = (Hashtable) aVector.get(j);
String title = (String) hm.get("title");
String describ = (String) hm.get("describ");
Label z = new Label(title);
Label zz = new Label(describ);
f.add(z);
f.add(zz);
}
} catch (IOException ex) {
}
}
tbh i didnt get your problem concretely but i still try to give you some shots so you can try out.
If i understand correctly you have 20 objects which contains values underlying?
So then you have a JSONArray, just iterate trough it and grab that JSONObject.
now just use parseJSON instead of parse as it is deprecated...
here is a short snippet of my code
JSONArray jsonTasks = new JSONArray(responseString);
for (int index = 0; index < jsonTasks.length(); index++) {
JSONObject jsonObject = (JSONObject) jsonTasks.get(index);
if (jsonObject != null) {
Map jsonMap = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(jsonObject.toString().getBytes(UTF8)), UTF8));
System.out.println(jsonMap.get("date"));

Android: IndexOutOfBounds Error when deleting row in ListView

I have an application that has 2 screens. The first screen has a ListView of movies with a row consisting of 3 Elements: Title, Date and Gross declared in strings.xml. The user has the option of adding a movie by clicking the menu button, which sends him to another screen. The second screen has 3 Edit texts that correspond to Title Date and Gross, which is alphabetically sorted straight away when it returns to screen 1.
Similarly, the user can also Edit/Delete entries by long clicking a row thatbrings up a context menu. The Edit function works like this:
a.) User long clicks Titanic and chooses Edit
b.) Row gets deleted, and user is brought to screen 2
c.) Edit texts are populated with the initial data from the deleted Row
d.) When user edits data, new movie is added at the bottom of the ListView.
The problem arises when the user deletes this new movie at the bottom of the ListView. Logcat gives a
java.lang.IndexOutOfBoundsException: Invalid index 50, size is 50
Here is my code (Take note I am using Perst to persist data, but I don;t think that won't really matter with my problem):
case R.id.contextedit:
Lab9_082588FetchDetails row = (Lab9_082588FetchDetails) getListView()
.getItemAtPosition(info.position);
Intent editData = new Intent(MovieList.this, Lab9_082588Edit.class);
String startTitle = row.getTitle();
String startGross = row.getGross();
String startDate = row.getDate();
editData.putExtra(Lab9_082588Edit.TITLE_STRING, startTitle);
editData.putExtra(Lab9_082588Edit.GROSS_STRING, startGross);
editData.putExtra(Lab9_082588Edit.DATE_STRING, startDate);
startActivityForResult(editData, MovieList.EDIT_MOVIE);
int posEdit = info.position;
String editTitle = results.get(info.position).getTitle();
results.remove(posEdit);
adapter.notifyDataSetChanged();
//Perst
Index<Lab9_082588FetchDetails> rootEdit = (Index<Lab9_082588FetchDetails>) db
.getRoot();
rootEdit.remove(editTitle, results.get((int) info.id));
db.setRoot(rootEdit);
return true;
Edit Class:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection using item.getItemId()
switch (item.getItemId()) {
case R.id.edit:
next();
break;
}
return true;
}
private void next() {
// TODO Auto-generated method stub
EditText movieTitle = (EditText) findViewById(R.id.etTitle);
EditText movieGross = (EditText) findViewById(R.id.etGross);
EditText movieDate = (EditText) findViewById(R.id.etDate);
String title = movieTitle.getText().toString();
String gross = movieGross.getText().toString();
String date = movieDate.getText().toString();
if ((title.length() > 0) && (gross.length() > 0)
&& (date.length() == 4)) {
Intent hobby = getIntent();
hobby.putExtra(Lab9_082588Edit.TITLE_STRING, title);
hobby.putExtra(Lab9_082588Edit.GROSS_STRING, gross);
hobby.putExtra(Lab9_082588Edit.DATE_STRING, date);
setResult(RESULT_OK, hobby);
finish();
}
}
Delete function:
int posDelete = info.position;
String deleteTitle = results.get(
info.position).getTitle();
results.remove(posDelete);
adapter.notifyDataSetChanged();
Index<Lab9_082588FetchDetails> rootDelete = (Index<Lab9_082588FetchDetails>) db
.getRoot();
rootDelete.remove(deleteTitle,
results.get(info.position));
db.setRoot(rootDelete); //Perst
return;
OnActivityResult (Edit):
case EDIT_MOVIE:
Lab9_082588FetchDetails edittedMovie = new Lab9_082588FetchDetails();
NumberFormat formatterEdit = new DecimalFormat("###,###,###");
edittedMovie.setTitle(data
.getStringExtra(Lab9_082588Add.TITLE_STRING));
edittedMovie.setGross("$"
+ formatterEdit.format(Double.parseDouble(data
.getStringExtra(Lab9_082588Add.GROSS_STRING))));
edittedMovie.setDate(data
.getStringExtra(Lab9_082588Add.DATE_STRING));
results.add(edittedMovie);
adapter.notifyDataSetChanged();
Populating the Listview:
for (int i = 0; i < items.size(); i++) {
Lab9_082588FetchDetails sr = new Lab9_082588FetchDetails();
sr.setTitle(items.get(i).getTitle());
sr.setGross(items.get(i).getGross());
sr.setDate(items.get(i).getDate());
results.add(sr);
Collections.sort(results, ignoreCaseStart);
}
How do I remedy this?
This problem occurs because in your delete function, you first remove the element from the results collection("results.remove(posDelete);"), and then, a few lines later, you call "results.get(info.position)" to fetch a parameter for the rootDelete.remove call, but which is already removed.
If the element is the last element of your collection, let's say the 50th element, the value for "info.position" is 50. You remove one element, so the number of elements is now 49. In the rootDelete.remove line you call results.get(50), which produces the error.

android xml node parse array adapter weird

I have an odd problem, (see shorter version at the bottom first please)
When my activity starts for the first time, the listview shows the dataset fine. The adapter is a custom adapter which shows 2 rows of text and an image. I call an asynctask upon a click event to the listview, the dataset updates in accordance with whatever was clicked on in the listview - more specifically the arrays which are associated with the adapter become rewritten with the parsings of some xml, and then notifyachapterdatasetchanged method is called to update the listview in the onPostExecute function. However I always get NullPointerException when I am iterating through some xml (which is very well formed and validates). ALso its worth mentioing that the algorithm that parses the desired values is good, because as mentioned above, if i write to just 1 element of the array then I dont get the error I just get the last node value so its looping in the correct places. i.e If I simple try to copy the current node value I am parsing during the loop into, say, producyTypes[0] then the last value from within the loop actually makes it to the listview as it constantly overwrites this elemet of the array
Here is my code.`
public class main extends Activity implements OnItemClickListener
{
String selectedType="";
ListView lview3;
ImageView iv;
ListViewCustomAdapter adapter;
String test = "";
List<String> ls;
String productTypes[] = {"Monitor","Components","Systems","Laptops","Flash / Usb Memory",
"Networking","Cables","Peripherals","Sound and Vision", "Software"};
String productsIncluded[] = {"Sizes (inches) 17, 19, 20",
"Motherboards, PSU, Cases, Fans/Heatsinks/Coolers, Barebones Systems, Blue-Ray/DVD. Card Readers, Controller Cards, Drive Enclosures, Sound Cards",
"Bundles, Switches and Hubs, Print Servers, Accessories/Modules",
"Cables for: Drives, Networking, HDMI/Monitor, Audio/Video, USB/Firewire, Power, Miscellaneous",
"Mice, Connectors, Bluetooth Devices",
"Mp3/Mp4 Solar Panel",
"Anti-Virus, Internet Security, Operating Systems, Office,,
"",
""};
private static int images[] = {R.drawable.monitor, R.drawable.components, R.drawable.systems,
R.drawable.laptops, R.drawable.flashusb, R.drawable.networking, R.drawable.cables, R.drawable.
peripherals, R.drawable.soundandvision, R.drawable.software};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv = (ImageView)findViewById(R.id.ImageView01);
iv.setImageResource(R.drawable.logo);
iv.setVisibility(View.VISIBLE);
lview3 = (ListView) findViewById(R.id.listView3);
adapter = new ListViewCustomAdapter(main.this, productTypes, productsIncluded, images);
lview3.setAdapter(adapter);
lview3.setOnItemClickListener(main.this);
}
#Override
public void onItemClick(AdapterView arg0, View arg1, int position, long id) {
selectedType = "";
if(position == 0)
{
selectedType= "Monitors";
}
if(position == 1)
{
selectedType= "Hard Drives";
}
Toast.makeText(this, Integer.toString(position), Toast.LENGTH_SHORT).show();
new async().execute();
/*
Intent intent = new Intent(getApplicationContext(),activitywo.class);
Bundle bundle =new Bundle();
bundle.putString("selectedType",selectedType);
intent.putExtras(bundle);
startActivity(intent);
//Toast.makeText(this, "Title => "+productTypes[position]+" \n Description => "+productsIncluded[position], Toast.LENGTH_SHORT).show();
*/
}
private class async extends AsyncTask<String, Void, Void> {
// UI Thread
protected void onPreExecute() {
}
// automatically done on worker thread (separate from UI thread)
protected Void doInBackground(final String... args) {
try{
Resources res = getResources();
InputStream in;
in = res.openRawResource(R.raw.core);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(in);
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("entry");
count=0;
for(int i =0;i<items.getLength();i++){
Node item = items.item(i);
NodeList properties = item.getChildNodes();
//productsDefinedByTypeArray = new String[properties.getLength()];
for(int j = 0;j<properties.getLength();j++){
Node property = properties.item(j);
String name = property.getNodeName();
if(name.equalsIgnoreCase("g:product_type")){//everytime we hit g:product_type grab the value
String strText = property.getFirstChild().getNodeValue();
if(strText.contains(selectedType)){
//
for(int k = 0;k<properties.getLength();k++){
Node propertysecond = properties.item(k);
String namesecond = propertysecond.getNodeName();
if(namesecond.equalsIgnoreCase("title")){//everytime we hit title grab the value
String strTextsecond = propertysecond.getFirstChild().getNodeValue();
productTypes[0] = strTextsecond;
yo = strTextsecond;
count++;
}
}
}
}
}
}
The code crashes at the point where I am trying to copy the value of a "title" node that I parse out of my xml file into the list-String-. I am using a list-string- to show that even if you try and copy the value into the array itself (the array that is associated with the adapter), even if you comment out the notifydatasetchanged () line the program still crashes. The xml is well formed and very consistent. I know this because (aecept the fact its really small and I have read it all) ! Why can I not copy every node value into my array/list whilst the loop is in progress?
Any help is massively appreciated. Thank you.
Shorter version:
I cannot write to the List
if(strText.contains(selectedType)){
//
for(int k = 0;k<properties.getLength();k++){
property = properties.item(k);
name = property.getNodeName();
if(name.equalsIgnoreCase("title")){//everytime we hit title grab the value
String strTextsecond = property.getFirstChild().getNodeValue().toString();
ls.add(strTextsecond.toString());
//test = strTextsecond;
}
}
}
Maybe you forget initialize ls? I don't find in your code something like:
ls = new List<String>();

Categories

Resources