Better solving method other than if -else - android

Thanks in advance for any reply. I currently working on android application that let user select several option from 10 spinner type(dropdownlist). But for every onChanged click in spinner, i have to check other spinner item for making a query in cursor. I thinking to use if-else statement to solve it as if-else statement was the easier way to approach the outcome i need but it will consume too many LOC and is not very efficient when modification of code is needed.
Sorry to demand solution from you guy but i cant figure a better method.

It is possible for you to store the last known value of the dropdown into a variable, and then run through those stored variables on click.
var storedVaribles[10];
OnChanged(int i, var changedVariable)
{
storedVariables[i] = changedVariable;
checkWithAllStoredVariables(storedVariables);
}
This is only pseudocode, but it should give you an idea of the direction to head with the solution.
erhaps this type of question would be more appropriate on CodeReview.

You have control of your spinner Adapters. Try to construct your data such that you directly obtain the information that belongs in your query. The basic idea is to have an object like this:
class SpinnerItem {
String displayTitle;
String querySyntax;
public SpinnerItem(String title, string sql) {
displayTitle = title;
querySyntax = sql;
}
}
Then make a SpinnerAdapter that keeps an array or a list of these objects. In getView(), you would bind the displayTitle to a TextView that the user sees. When you want to compose your query, you can call
SpinnerItem item = adapter.getItem(spinner.getSelectedItemPosition());
// use item.querySyntax in your query
As a very simple example, suppose I have a table with contacts, and each contact has either an email or phone number. I want the query to filter on this type based on the selected spinner item. Here's how I might build it:
List<SpinnerItem> items = new ArrayList<SpinnerItem>();
items.add(new SpinnerItem("All", "1"));
items.add(new SpinnerItem("Phone numbers only", "type = 'phone'"));
items.add(new SpinnerItem("Emails only", "type = 'email'"));
MySpinnerAdapter adapter = new MySpinnerAdapter(items);
spinner.setAdapter(adapter);
// later when building query ...
StringBuilder builder = new StringBuilder("select * from table where ");
SpinnerItem item = adapter.getItem(spinner.getSelectedItemPosition());
builder.append(item.querySyntax);
String sql = builder.toString();

Related

How to build a ListView based on JSON object and pass its data around after onItemClick

Not sure if the title accurately describes what I'm trying to do, but here goes...
My app receives the following JSON object from the server:
[{"id":"0","code":"1234","name":"thing"}]
I want to create a ListView all of those items (the amount of items in the JSON always varies) and only display the value of the "name" field in my ListView. So my list should look like this for the user:
thing
another thing
third thing
...
Now I want to retrieve the value of "code" from the JSON object for that particular "name" when it is clicked on the ListView. So with the object above it would give me "1234" when "thing" was clicked.
Later I wish to send the "code" to another activity and do some followup queries to the database using it, but for now I can't seem to get any of this to work.
I am aware that with what I have right now, the "code" is not visible to the program because I build my ListView from Strings of "name" from the JSON object
I have the following OnClickListener
search_results.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// ListView item is clicked!
}
});
My ListView is built like this:
JSONArray jsonArray = new JSONArray(json);
String[] stocks = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
stocks[i] = obj.getString( "name" );
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, stocks);
search_results.setAdapter(arrayAdapter);
Note: I have tried to use MatrixCursor, but after hours of fiddling around with it, I just gave up... Basically I built a MatrixCursor the same way I built my stocks[] and was hoping to return the index of the clicked ListView item and then just use that index on the MatrixCursor because I assume they would be pointing to the same thing? I'm not sure this is the right way to do this though. And in the end I couldn't figure it out anyway.
You have to create an object, POJO, reflecting your JSON object. Something like this :
class MyObject {
String id;
String code;
String name;
}
Then, use Gson to creates your list of objects from your JSON.
After that, you will be able to create an Adapter to deal with MyObject class instead of String. It would be easier to retrieve the information of the item you've clicked.
To achieve what you ask I think it would be a good idea for you to consider using RecyclerView instead of ListView.
1. Create a simple POJO class
And parse your JSON into, then store the POJO in an ArrayList.
class MyPojo{
private String id;
private String code;
private String name;
//Dont forget to add your getters and setters...
}
2. Switch your ListView for RecyclerView
I suggest you take a look at this tutorial for using Recycler View.
Recycler View Tutorial
From there on everything else would be pretty intuitive.
If you need any more help comment.

Filter a listview instead of re-querying the database with more specific criteria

The subject doesn't seem to have been discussed a lot in details so I am gonna explain my situation as well as possible to make it clear and hopefully get some explanations.
My app allows the user to get information about places : there are different menus with different buttons corresponding to categories of places (food/ fastfood, restaurants, ... OR stores/shops, .... and so on). The user clicks on the button of his choice, it will send a request to my database and display a listview with the results. This way :
It is one example, but there are 16 possibilities like this, and everytime it's opening the same activity (ResultListViewActivity) but displaying different content.
I want the user to be able to make more accurate research, so there is a filter mode as you can see on picture 3. The window appearing allows to choose some more criteria. What I planned so far was to fill some variable everytime the user clicks on something. Like if he chooses to pay with a credit card, VALUECARD = X, if budget = something then VALUEBUDGET = Y and so on and when you click on OK it sends all the value package to a method querying the database and open a new listview with the results. It would definitely works, and I know how to do. But I also think it's not really a good way to query the database every time, why not searching directly in the list view ?
I know how to query the database, as my method is working to display listview (see picture 2), but I have no idea how to query a listview, especially when some columns from the database I would use in my filering are not imported in my cursor and then in my listview. I guess I would first have to import every column I might need for filtering.
Here is the code of my method displaying the listview so you see how my cursor is filled and my adapter is made :
private void displayListView() {
// getExtra
Bundle bundle = getIntent().getExtras();
String title = bundle.getString("title", "Choose here :");
String inInterval = bundle.getString("inInterval");
Log.d(TAG, "inInterval = " + inInterval);
poititle.setText(title);
// put the results of the method in a cursor
Cursor c = dbHelper.findPoiInTable(inInterval);
String[] columns = new String[] { DatabaseAdapter.COL_NAME,
DatabaseAdapter.COL_STREET, DatabaseAdapter.COL_WEBSITE,
DatabaseAdapter.COL_TELEPHONE, DatabaseAdapter.COL_REMARKS,
DatabaseAdapter.COL_PRICE };
int[] to = new int[] { R.id.name, R.id.street, R.id.website,
R.id.telephone, R.id.remarks, R.id.price };
cursorAdapter = new SimpleCursorAdapter(this, R.layout.poi_info, c,
columns, to, 0);
ListView listView = (ListView) findViewById(R.id.poilistview);
// Assign adapter to ListView
listView.setAdapter(cursorAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// Comportement des éléments de la listview
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(getApplicationContext(),
POIActivity.class);
String name = ((TextView) view.findViewById(R.id.name))
.getText().toString();
String website = ((TextView) view.findViewById(R.id.website))
.getText().toString();
String telephone = ((TextView) view
.findViewById(R.id.telephone)).getText().toString();
String remarks = ((TextView) view.findViewById(R.id.remarks))
.getText().toString();
String price = ((TextView) view.findViewById(R.id.price))
.getText().toString();
// i.putExtra(ID_EXTRA, name) ;
i.putExtra(ID_NAME, name);
i.putExtra(ID_WEBSITE, website);
i.putExtra(ID_TELEPHONE, telephone);
i.putExtra(ID_REMARKS, remarks);
i.putExtra(ID_PRICE, price);
startActivity(i);
}
}); }
In this particular case, how could I for example filter the "COL_PRICE" which is in my cursor ? To be more precise, in my filter menu, when the user sets the budget and we get a value, how to use this value in relation to the value from COL_PRICE and keep elements under the given value ?
Thanks for any information !
The easiest solution with your current Code would be using adding a FilterQueryProvider to your adapter, but this will eventually start a new query in your database.
If you really don't want to do a new query on your database, you would have to implement your own custom adapter for your ListView. This will be a whole lot more work than the first solution and is probably slower too.

How to attach some "metadata" to Android Listview items?

class Venue {
private int id;
private String name;
}
I populate the ListView with something like
List<String> venueNames = data.getVenueNames();
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, venueNames));
So after the user selects a particular list item, I'd like to do a SQLite query with the venue id, but this information is lost when creating the venue names. How do you guys solve this?
EDIT: I should mention that it isn't guaranteed that venue name is unique.
Your problem is here:
List<String> venueNames = data.getVenueNames();
Don't do that. You are the one "losing" the information. If you don't want to lose it, don't lose it.
The simplest thing is to create an ArrayAdapter<Venue>, and have Venue's toString() return name. Then, calling getItem() on your ArrayAdapter<Venue> will return a Venue.

Can I add data from different tables of the same database into each row of a ListView in Android?

Can I add data from different tables of the same database into each row of a ListView in Android?
I have a vendor app and I want to add data from one standard items list table and one daily table to the list view.
If both tables have the same row format (or at least you're selecting the same type of rows from both tables), you can combine them into a single query with UNION. See the sqlite select query documentation for more info on UNIONs.
I think you mean that the query joins two different tables; is that correct?
If you're using a SimpleCursorAdapter, then you can use a CursorToStringConverter to provide the labels for the ListView. Here's an example:
// choices to be displayed in the AutoCompleteTextView.
adapter.setCursorToStringConverter(new CursorToStringConverter() {
public String convertToString(android.database.Cursor cursor) {
final int columnIndex1 = cursor.getColumnIndexOrThrow("col1");
final String str1 = cursor.getString(columnIndex1);
final int columnIndex2 = cursor.getColumnIndexOrThrow("col2");
final String str2 = cursor.getString(columnIndex2);
return str1 + str2;
}
});
If you want to data from each of the tables to be presented in separate Views (instead of within a single TextView), then you can use a SimpleCursorAdapter.ViewBinder to update the Views. (Here's an example of a ViewBinder. I wrote this to work with a Spinner, but it works the same way with a ListView.)

Android - configure Spinner to use array

I declare my Spinner in the following manner (it's very static so I
have 2 string arrays in array.xml for titles and values)
<Spinner
android:id="#+id/searchCriteria"
android:entries="#array/searchBy"
android:entryValues="#array/searchByValues" />
I expect spinner.getSelectedItem() to return an array [title, value]
but in fact it returns just a title String. Is it ignoring
android:entryValues? How do I get a value, not a title from it? Is
this doable with XML only or do I need to create adapter and do it
programmatically?
Rather than the dual array method, why not fill your ArrayAdapter programmatically with objects of a known type and use that. I've written a tutorial of a similar nature (link at the bottom) that does this. The basic premise is to create an array of Java objects, tell the spinner about the, and then use those objects directly from the spinner class. In my example I have an object representing a "State" which is defined as follows:
package com.katr.spinnerdemo;
public class State {
// Okay, full acknowledgment that public members are not a good idea, however
// this is a Spinner demo not an exercise in java best practices.
public int id = 0;
public String name = "";
public String abbrev = "";
// A simple constructor for populating our member variables for this tutorial.
public State( int _id, String _name, String _abbrev )
{
id = _id;
name = _name;
abbrev = _abbrev;
}
// The toString method is extremely important to making this class work with a Spinner
// (or ListView) object because this is the method called when it is trying to represent
// this object within the control. If you do not have a toString() method, you WILL
// get an exception.
public String toString()
{
return( name + " (" + abbrev + ")" );
}
}
Then you can populate a spinner with an array of these classes as follows:
// Step 1: Locate our spinner control and save it to the class for convenience
// You could get it every time, I'm just being lazy... :-)
spinner = (Spinner)this.findViewById(R.id.Spinner01);
// Step 2: Create and fill an ArrayAdapter with a bunch of "State" objects
ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(this,
android.R.layout.simple_spinner_item, new State[] {
new State( 1, "Minnesota", "MN" ),
new State( 99, "Wisconsin", "WI" ),
new State( 53, "Utah", "UT" ),
new State( 153, "Texas", "TX" )
});
// Step 3: Tell the spinner about our adapter
spinner.setAdapter(spinnerArrayAdapter);
You can retrieve the selected item as follows:
State st = (State)spinner.getSelectedItem();
And now you have a bona fide Java class to work with. If you want to intercept when the spinner value changes, just implement the OnItemSelectedListener and add the appropriate methods to handle the events.
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
// Get the currently selected State object from the spinner
State st = (State)spinner.getSelectedItem();
// Now do something with it.
}
public void onNothingSelected(AdapterView<?> parent )
{
}
You can find the whole tutorial here:
http://www.katr.com/article_android_spinner01.php
So if you came here because you want to have both label and value in the Spinner - here's how I did it:
Just create your Spinner the usual way
Define 2 equal size arrays in your array.xml file. One for labels, one for values
Set your Spinner with android:entries="#array/labels"
In your code - when you need a value do something like this (no you don't have to chain it)
String selectedVal = getResources().getStringArray(R.array.values)[spinner
.getSelectedItemPosition()];
And remember - these 2 arrays have to match each other as far as number slots and positions
Abort, abort! I don't know what got into me but Spinner does not support android:entryValues attribute. That one is actually from ListPreference which does a similar thing (displays list of items in pop-up dialog). For what I need I will have to (alas) use the SpinnerAdapter

Categories

Resources