ANSWERED BY ME
I am confused where to put and how to use my custom adapter.
My Parser.class has its own Adapter and my MainActivity is passing 3 parameters to the Parser.class (context, url, listview).
(Making my problem simple)
After creating a custom layout, custom adapter, and instantiating my custom adapter, I don't know what to do.
I tried instantiating my custom adapter in my MainActivity then creating MainActivity m = new MainActivity(); in my Parser.class and just use the textviews of my custom listview like m.name_tv.setText(name); and m.price_tv.setText(price) then changing the android.R.layout.simple_list_item_1 to my custom listview layout R.layout.list_layout.
I was just experimenting because I'm having trouble understanding.
Please help.
This is my Parser.class
public class Parser extends AsyncTask<Void,Integer,Integer> {
Context c;
ListView lv;
String data;
ArrayList<String> categories = new ArrayList<>();
ProgressDialog pd;
public Parser(Context c, String data, ListView lv) {
this.c = c;
this.data = data;
this.lv = lv;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Parsing Data");
pd.setMessage("Please Wait...");
pd.show();
}
#Override
protected Integer doInBackground(Void... params) {
return this.parse();
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if(integer == 1)
{
//ADAPTER
ArrayAdapter<String> adapter = new ArrayAdapter<String>(c, android.R.layout.simple_list_item_1, categories);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position == 0){
}
}
});
}else
{
Toast.makeText(c,"Unable to Parse",Toast.LENGTH_SHORT).show();
}
pd.dismiss();
}
//PARSE RECEIVED DATA
private int parse(){
try
{
//ADD THAT DATA TO JSON ARRAY FIRST
JSONArray ja = new JSONArray(data);
//CREATE JO OBJECT TO HOLD A SINGLE ITEM
JSONObject jo = null;
categories.clear();
//LOOP THROUGH ARRAY
for(int i =0 ; i<ja.length();i++)
{
jo = ja.getJSONObject(i);
//RETRIEVE NAME
name=jo.getString("item_name");
price=jo.getString("item_price");
//ADD TO ARRAY LIST
categories.add(name + " " + price);
}
return 1;
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
}
Should it be better to not separate the classes or it will work the same?
you should get response from web service and parse it (json object or json array) in one step
you can reach this in good way ,
First create class with json attribute name
in your case
Class JsonItem {
string item_name;
string item_price;
// create getter and setter
}
Second use Gson to parse your response
Gson gson = new Gson();
// 1. JSON to Java object, read it from a file.
JsonItem staff = gson.fromJson(YOUR_JSON_Here, JsonItem.class);
that is all
Related
I have wrote the code to populate List View with single string. But, I don't know how to populate with 2 strings.. Somebody, please help me out.
here is my code:
public class BackTask extends AsyncTask<String, Void, String> {
ArrayList<FlowerAdapter.Flowers> flowersList = new ArrayList<FlowerAdapter.Flowers>();
String url = "http://113.193.30.155/MobileService/MobileService.asmx/GetSampleData";
#Override
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
String content = FlowerAdapter.HttpULRConnect.getData(url);
return content;
}
#Override
protected void onPostExecute(String s){
try {
JSONArray ar =new JSONArray(s);
for (int i = 0; i < ar.length(); i++){
JSONObject jsonObject=ar.getJSONObject(i);
here i want to get 2 strings "NAME"&"PERCENTAGE"....but i dont know how to get the another string and bind it in List View.
FlowerAdapter.Flowers flowers= new FlowerAdapter.Flowers();
flowers.setName(jsonObject.getString("NAME"));
flowersList.add(flowers);
FlowerAdapter adapter=new FlowerAdapter(getContext(),R.layout.flower_list_xml,flowersList);
listView = (ListView)getView().findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setVisibility(View.VISIBLE);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
first, add all the field in your Flowers class with setters and gettersThen set it in the object which you are passing to adapter.
i have created a setter for this second string and called it...thats all..
flowers.setPercentage(jsonObject.getString("Percentage");
So, I used Android - configure Spinner to use array to try and display just one field of a custom java class. My Java class is as follows (it is a part of my Google App Engine backend)
public class CropVariety {
private String varietyId;
private String varietyName;
public String getVarietyId() { return varietyId; }
public String getVarietyName() {
return varietyName;
}
public void setVarietyId(String data) {varietyId = data; }
public void setVarietyName(String data) {
varietyName = data;
}
public String toString()
{
return varietyName;
}
}
and then in the activity Async task, I have the following in Post Execute
super.onPostExecute(result);
varietyList = result;
spinner = (Spinner) findViewById(R.id.variety_spinner);
spinner.setSelection(0);
dataAdapter = new ArrayAdapter(context,android.R.layout.simple_spinner_item, varietyList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
dataAdapter.notifyDataSetChanged();
spinner.setAdapter(dataAdapter);
spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
The OnItemSelectedListener is implemented as follows:
public void onItemSelected(AdapterView parent, View view, int pos, long id) {
// String selectedItem = parent.getItemAtPosition(pos).toString();
CropVariety selectedItem = (CropVariety) parent.getItemAtPosition(pos);
//check which spinner triggered the listener
switch (parent.getId()) {
case R.id.variety_spinner:
selectedVarietyName = selectedItem.getVarietyName();
selectedVarietyId = selectedItem.getVarietyId();
break;
}
So while selectedVarietyName and selectedVarietyId get the right values, each item on the drop down list looks as follows:
{"varietyId":"sefs","varietyName":"asfd"}
I followed the link and don't know why the variety name isn't being displayed in the spinner. Thank you
you are downloading json Object from that link .. you have to parse th json in your doInBackground .. and store the result in a list to use it later in the postExecute here is an exemple:
class ModifierParam extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ActivityMed.this);
if (action.equals("rdvmed")) {
pDialog.setMessage(getString(R.string.enrParam));
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
}
protected String doInBackground(String... args) {
JSONObject json;
List<NameValuePair> params = new ArrayList<NameValuePair>();
//here are the password and email for login
params.add(new BasicNameValuePair("Email", email));
params.add(new BasicNameValuePair("Mdp", mdp));
json = jsonParser.makeHttpRequest(url_parametres,
"POST", params);
}
try {
if(json != null && !json.isNull("yourArrayName")){
list.clear();
if (json.has("yourArrayName")) {
JSONArray ja = json.getJSONArray("yourArrayName");
for (int i = 0; i < ja.length(); i++) {
JSONObject c = ja.getJSONObject(i);
String varietyNames= String.valueOf(c.getInt("varietyName"));
String varietyId= c.getString("varietyId"));
//store data in the list
list.add(new YourObjectName(varietyName, varietyId));
}
}
}
}
}} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
//here you create your adapter from that list
// and then Spinner.setAdapter(the Adapter);
}
}
you need jsonParser i think you have it... if you dont here it is :
http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
now your data will be displayed correctly
Well, I don't know if the title is clear, so now I'll explain everything better.
I have parsed some JSON objects. After parsing, I need to show them into a custom listview.
The JSON objects are correctly parsed into string, because I have first show them into common textviews (just for a test).
Also the custom listview is working, because I have first added some values "manually" (again, just for testing it).
Here my problem:
Now I want to add the JSON objects (parsed into string) into my custom listview. I've tried every "tip and trick" I know, unsuccessfully. After two days of working, I've decided to ask you.
Before posting the code: the http request for parsing JSON objects is made with this library.
Here the code
Getprofiledata.java
public class Getprofiledata extends ActionBarActivity {
String num;
Boolean ok=true;
int i=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.data);
String url = "URL FOR JSON OBJECTS";
ListView listadata = (ListView) findViewById(R.id.listadata);
final List<Data> datalist = new LinkedList <Data>();
AsyncHttpClient client = new AsyncHttpClient();
client.get(url,new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
ok=true;
i=1;
num = Integer.toString(i);
while(ok==true){
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject object = jsonObject.getJSONObject(num);
/*********
* THESE ARE THE STRINGS I NEED TO ADD TO MY CUSTOM LISTVIEW
*********/
String record1 = object.getString("first");
String record2 = object.getString("second");
String record3 = object.getString("third");
String record4 = object.getString("fourth");
String record5 = object.getString("fiveth");
i++;
num = Integer.toString(i);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ok=false;
}
}
}
#Override
public void onFailure(Throwable e,String response) {
Log.d("AREQ","http GET request failed");
}
});
/*********
* HERE WE CAN ADD VALUES TO MY CUSTOM LISTVIEW
* HOW CAN I PASS THE PREVIOUS STRING IN THIS STATEMENT?
*
* THIS IS THE METHOD:
* datalist.add(new Data(record1,record2,record3,record4,record5));
*********/
//HERE THE ADAPTER FOR MY CUSTOM LISTVIEW
Getprofiledata_customadapter adapter = new Getprofiledata_customadapter(this, R.layout.data_riga, datalist);
listadata.setAdapter(adapter);
}
}
I hope I've been clear. Can you help me? I'm desperate! :(
Thanks in advance
Edit: here my Getprofiledata_customadapter.java
public class Getprofiledata_customadapter extends ArrayAdapter<Data>{
public Getprofiledata_customadapter(Context context, int textViewResourceId,
List <Data> objects) {
super(context, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.data_riga, null);
TextView firstrecord = (TextView)convertView.findViewById(R.id.tv1);
TextView secondrecord = (TextView)convertView.findViewById(R.id.tv2);
TextView thirdrecord = (TextView)convertView.findViewById(R.id.tv3);
TextView forthrecord = (TextView)convertView.findViewById(R.id.tv4);
TextView fivethrecord = (TextView)convertView.findViewById(R.id.tv5);
Data c = getItem(position);
firstrecord.setText(c.getRecord1());
secondrecord.setText(c.getRecord2());
thirdrecord.setText(c.getRecord3());
forthrecord.setText(c.getRecord4());
fivethrecord.setText(c.getRecord5());
return convertView;
}
}
Basically you just pre-create the List first. Then with that data create an adapter and set it to your ListView.
At the moment you just loop through the data without saving it at all.
It would look something like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.data);
mListView = (ListView) findViewById(R.id.listadata);
String url = "URL FOR JSON OBJECTS";
AsyncHttpClient client = new AsyncHttpClient();
client.get(url,new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
ok=true;
i=1;
num = Integer.toString(i);
while(ok==true){
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject object = jsonObject.getJSONObject(num);
/*********
* THESE ARE THE STRINGS I NEED TO ADD TO MY CUSTOM LISTVIEW
*********/
String record1 = object.getString("first");
String record2 = object.getString("second");
String record3 = object.getString("third");
String record4 = object.getString("fourth");
String record5 = object.getString("fiveth");
// Save strings to your list
mData.add(new Data(record1,record2,record3,record4,record5));
i++;
num = Integer.toString(i);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ok=false;
}
}
// When the data loop is over create the adapter and set it to your ListView
Getprofiledata_customadapter adapter = new Getprofiledata_customadapter(this,
R.layout.data_riga, mData);
mListView.setAdapter(adapter);
}
#Override
public void onFailure(Throwable e,String response) {
Log.d("AREQ","http GET request failed");
}
});
}
I need to update my ListView content (which is retrieved from a database) each time when a button is clicked. I am trying to include a book search functionality in my android application.
For that I am taking some keywords as input.On a button click the book details matching the key word is retrieved from database and is displayed in the list view in the same layout.
The code I have written will create a new ListView with updated content on each button click and display it below the previous ListView.Which I need to correct.
A preferred solution will be to update the list view content on a button click.
Removing the previously displayed ListView is also acceptable.
For that I tried getListView().inValidate() but didn't work. notifyDataSetChanged() also is not working .Please help :)
public class searchActivity extends ListActivity {
String keyword;
Button bsearch;
EditText input;
JSONParser jParser = new JSONParser();
JSONArray books = null;
SimpleAdapter adapter;
ArrayList<HashMap<String, String>> booksList;
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState{
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
bsearch=(Button)findViewById(R.id.search);
input=(EditText)findViewById(R.id.inputSearch);
booksList = new ArrayList<HashMap<String, String>>();
adapter=newSimpleAdapter(searchActivity.this,booksList,R.layout.search_list,new String[]{"bookname"},new int[] {R.id.bookname});
getListView().setAdapter(adapter);
bsearch.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
keyword=input.getText().toString();
new LoadAll().execute();
}
});
}
class LoadAll extends AsyncTask<String, String, String> {
protected String doInBackground(String... args) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("keyword", keyword));
JSONObject json = Jparser.makeHttpRequest("http://10.0.2.2 /libraryconnect/search_book.php", "GET", params);
Log.d("All books: ", json.toString());
try {
int success = json.getInt("success");
if (success == 1) {
books = json.getJSONArray("books");
for (int i = 0; i < books.length(); i++) {
JSONObject c = books.getJSONObject(i);
String name = c.getString("bookname");
HashMap<String, String> map = new HashMap<String, String>();
map.put("bookname",bookname);
booksList.add(map);
}
} else {
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});
}
}
}
In your onClick(View v), call notifyDataSetChanged () from your adapter
You can change data set of your list view and then call notifyDataSetChanged() on it,instead of creating new list view or new adapter for it.
You can find what you need to know in Android ListView - Tutorial.
I want to fill a ListFragment with certain objects loaded from my MySql database.
It has to load the first 10 'objects' from my ResultSet.
I want to use an AsyncTaskLoader for this and put the loaded object in a ListItem each time I retreive it from the database.
Can anybody help me with this one? Tried searching for good examples or tutorials but I haven't really found something that's really useful...
Create your adapter with a new list in your preexecute method. Set that adapter to your listview.
Then in doInBackground read your database, create objects to fit in your list, but don't add them. Pas each object after made as parameter for your publishprogress method.
In onProgressUpdate add your object to the list and notify your adapter that the dataset is changed.
Below is an example for how I do it reading a twitter call.
private class parseTwitterTask extends AsyncTask<Void, TCListObject2, List<TCListObject2>> {
TCListObjectAdapter2 adapter;
List<TCListObject2> list;
#Override
protected void onPreExecute() {
list = new ArrayList<TCListObject2>();
ListView lv = (ListView)findViewById(R.id.twitterlist);
adapter = new TCListObjectAdapter2(list);
lv.setAdapter(adapter);
super.onPreExecute();
}
#Override
protected List<TCListObject2> doInBackground(Void... params) {
try {
String url = social.get("twittersearchurl");//"http://search.twitter.com/search.json?q=" + social.get("twitter");
String json = Internet.request(url, null);
JSONObject jo = new JSONObject(json);
if(jo.has("results")) {
JSONArray ar = jo.getJSONArray("results");
for(int i = 0; i < ar.length(); i++) {
TCListObject2 tweet = new TCListObject2();
JSONObject jobj = (JSONObject) ar.get(i);
tweet.id = "false";
tweet.img = jobj.getString("profile_image_url");
String text = jobj.getString("text");
text = Html.fromHtml(text).toString();
tweet.params.put(R.id.sub2, text);
String name = jobj.getString("from_user");
name = Html.fromHtml(name).toString();
tweet.params.put(R.id.text, name);
String time = jobj.getString("created_at");
tweet.params.put(R.id.sub1, Converter.timeToTimeAgo(time));
try {
tweet.time = new Date(time);
} catch(Exception e) {
e.printStackTrace();
}
tweet.celLayout = R.layout.cell_tweetobject;
publishProgress(tweet);
}
}
} catch(Exception e) {
e.printStackTrace();
}
return list;
}
#Override
protected void onProgressUpdate(TCListObject2... values) {
list.add(values[0]);
adapter.notifyDataSetChanged();
super.onProgressUpdate(values);
}