I am facing a problem, i have a listView that i fill using a custom array adapter, the issue is that when i use the custom array adapter, the data stored in the ArrayList won't show but if i use a normal ArrayAdapter the data will be shown. I need to use a custom array adapter to style the listview since i can't style it in the normal ArrayAdapter
here is the code:-
CustomAdapter adapter;
Context context;
ArrayList<String> data;
ListView listView;
private static String newline = System.getProperty("line.separator");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_production_comments);
//defining list view
listView = (ListView)findViewById(R.id.listView);
//defining data array list to store retrieved data from database
data = new ArrayList<String>();
adapter = new CustomAdapter(this,android.R.layout.simple_list_item_1, data);
listView.setAdapter(adapter);
context = this;
Toast.makeText(this,"Loading Please Wait..",Toast.LENGTH_LONG).show();
new AsyncLoadProdComments().execute();
}
protected class AsyncLoadProdComments extends AsyncTask<Void, JSONObject,
ArrayList<ProductionCommentsTable>> {
ArrayList<ProductionCommentsTable> ProductionCommentsTable = null;
#Override
protected ArrayList<ProductionCommentsTable> doInBackground(Void... params) {
// TODO Auto-generated method stub
RestAPI api = new RestAPI();
try {
JSONObject jsonObj = api.GetProductionComments();
JSONParser parser = new JSONParser();
ProductionCommentsTable = parser.parseProductionComments(jsonObj);
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("AsyncLoadProdDetails", e.getMessage());
}
return ProductionCommentsTable;
}
#Override
protected void onPostExecute(ArrayList<ProductionCommentsTable> result) {
// TODO Auto-generated method stub
for (int i = 0; i < result.size(); i++) {
//Log.d("Data1", String.valueOf(result));
data.add("Date: " + result.get(i).getDate().substring(0, 10) + newline + newline +
"Item: " + result.get(i).getItem() + newline + newline +
result.get(i).getComments());
}
adapter.notifyDataSetChanged();
Toast.makeText(context,"Loading Completed", Toast.LENGTH_SHORT).show();
}
}
private class CustomAdapter extends ArrayAdapter {
private Context mContext;
private int id;
private List <String>items ;
public CustomAdapter(Context context, int textViewResourceId , ArrayList<String> list )
{
super(context, textViewResourceId, list);
mContext = context;
id = textViewResourceId;
items = list ;
}
#Override
public View getView(int position, View v, ViewGroup parent)
{
View mView = v ;
if(mView == null){
LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = vi.inflate(id, null);
}
if(position % 2 == 0){
mView.setBackgroundColor(Color.CYAN);
}else{
mView.setBackgroundColor(Color.YELLOW);
}
return mView;
}
}
Your using of array adapter is wrong. It has own array to store data, so instead of adding your data to data array list you shoud add it to adapter. It has method add (T object)
Related
I have a A data stored in ArrayList< HashMap< String, String> > retrieved from JSON
in the form (i.e.)
[{price: =1685 name: =Monographie Der Gattung Pezomachus (Grv.) by Arnold F. Rster}]
And I need to show the all map elements into list form in Android.
I've tried many ways but I'm unable to do it .
Also help me to know about the layouts to use in it
EDITED:
MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(myarr_list);
setListAdapter(adapter);
And in the MySimpleArrayAdapter Class, in Constructor
public MySimpleArrayAdapter( ArrayList<HashMap<String,String>> pl) {
LayoutInflator inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
The control does not proceed after this,
MySimpleArrayAdapter Class
public class MySimpleArrayAdapter extends BaseAdapter{
ArrayList<HashMap<String, String>> ProductList = new ArrayList<HashMap<String, String>>();
LayoutInflater inflater;
#Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
//Constructor
public MySimpleArrayAdapter( ArrayList<HashMap<String,String>> pl) {
this.ProductList = pl;
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent) {
View myview = convertView;
if (convertView == null) {
myview = inflater.inflate(R.layout.show_search_result, null);
}
TextView price = (TextView) myview.findViewById(R.id.price);
TextView name = (TextView) myview.findViewById(R.id.name);
HashMap<String, String> pl = new HashMap<String, String>();
pl = ProductList.get(position);
//Setting
price.setText(pl.get("price"));
name.setText(pl.get("name"));
return myview;
}
}
I am editing here a onPostExecute class from SearchResultsTask extended by AsyncTask
protected void onPostExecute(JSONObject json) {
if (json != null && json.length() > 0) {
try {
JSONArray json_results = (JSONArray)(json.get("results"));
String parsedResult = "";
System.out.println("-> Size ="+ json_results.length());
for(int i = 0; i < json_results.length(); i++){
HashMap<String, String> map = new HashMap<String, String>();
JSONObject json_i = json_results.getJSONObject(i);
map.put("name: ",json_i.getString("name") + "\n");
map.put("price: ",json_i.getString("price") + "\n");
arr_list.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
System.out.println("-> Size =====arr_llist ="+ arr_list.size());
// CustomListAdapter adapter = new CustomListAdapter (arr_list);
//final StableArrayAdapter adapter = new StableArrayAdapter(this, R.id.result, arr_list);
// listview.setAdapter(adapter);
MyListActivity obj1 = new MyListActivity();
Bundle icicle = null;
obj1.onCreate(icicle);
}
public class MyListActivity extends Activity {
public void onCreate(Bundle icicle) {
// System.out.println("In my list Activity");
// super.onCreate(icicle);
//populate list
MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(this,arr_list);
// System.out.println("in 2");
adapter.getView(0, listview, listview);
listview.setAdapter(adapter);
}
}
#Override
public int getCount() {
return ProductList.size() ;
}
//Constructor
public MySimpleArrayAdapter( ArrayList<HashMap<String,String>> pl, Context c) {
this.ProductList = pl;
inflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
getSystemService() is method of context, you are calling it on instance of adapter.
I have research a lot on this but nothing satisfy me .Everyone give me the a solution put the adapter.notifyDataSetChanged() in runOnUiThread which i have already done bit didi not give me the solution.
My Code is below
public class FragmentActivity3 extends Fragment {
// Hashmap for ListView
ArrayList<Item> imageArry = new ArrayList<Item>();
CustomQuoteAdapter adapter;
String jsonstring;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
View rootView=inflater.inflate(R.layout.activity_fragment_activity1, container,false);
jsonstring=JsonClass.readData();
Log.d("JSon String ",jsonstring);
new GetQuotesInfo().execute();
adapter = new CustomQuoteAdapter(getActivity(), R.layout.list, imageArry);
ListView dataList = (ListView) rootView. findViewById(R.id.list);
dataList.setAdapter(adapter);
return rootView;
}
//Async Task to load data
class GetQuotesInfo extends AsyncTask<Void, Void, Void>
{
int count;
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
try {
JSONArray jsonarr=new JSONArray(Globals.jsonText);
count=jsonarr.length();
for(int i=0;i<count;i++)
{
HashMap<String, String> quoteinfo = new HashMap<String, String>();
String author="";
Log.d("Json","Reading");
JSONObject jsonobj=jsonarr.getJSONObject(i);
String name=jsonobj.getString("name");
quoteinfo.put("name", name);
JSONArray jarr=jsonobj.getJSONArray("quotes");
String[] myarr=new String[jarr.length()];
String[] myarr1=new String[jarr.length()];
for(int j=0;j<jarr.length();j++)
{
JSONObject jobj=jarr.getJSONObject(j);
author=jobj.getString("author");
String text=jobj.getString("text");
Log.d("Author ",author);
Log.d("Text ",text);
myarr[j]=text;
myarr1[j]=author;
}
imageArry.add(new Item(name,myarr1, myarr));
}
}
catch(Exception ex)
{
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
getActivity().runOnUiThread(new Runnable(){
public void run() {
adapter.notifyDataSetChanged();
}
});
}
}
}
My Adapter class is below
public class CustomQuoteAdapter extends ArrayAdapter<Item> {
Context context;
int layoutResourceId;
LinearLayout linearMain;
ArrayList<Item> data = new ArrayList<Item>();
public CustomQuoteAdapter(Context context, int layoutResourceId,
ArrayList<Item> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((FragmentActivity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
linearMain = (LinearLayout) row.findViewById(R.id.lineraMain);
Item myImage = data.get(position);
TextView txtview=new TextView(context);
String heading=myImage.heading;
txtview.setText(heading);
txtview.setTextColor(Color.BLUE);
txtview.setTextSize(20);
linearMain.addView(txtview);
for (int j = 0; j < myImage.getName().length; j++) {
TextView label1 = new TextView(context);
label1.setText(myImage.author[j]);
linearMain.addView(label1);
TextView label2 = new TextView(context);
label2.setText(myImage.name[j]);
linearMain.addView(label2);
}
// ImageView image = new ImageView(context);
// int outImage = myImage.image;
// image.setImageResource(outImage);
// linearMain.addView(image);
}
return row;
}
}
Can anyone give me the solution to resolve my error
onPostExecute() is automatically called on the UI thread, so you don't need the runOnUIThread()
Have you checked to make sure the data in your list is actually changing? Also I didn't go through the logic of your entire adapter, but this line looks like there's a typo. I'm guessing your IDE would have caught it if that typo weren't also in your resources file too though
linearMain = (LinearLayout) row.findViewById(R.id.lineraMain);
Not sure if that typo R.id.lineraMain is causing you problems.
This question already has answers here:
BaseAdapter class wont setAdapter inside Asynctask - Android
(4 answers)
Closed 9 years ago.
I have an asynctask that gathers comments, usernames, and numbers by using a JSON method. Then I have a class that extends BaseAdapter that suppose to put the comments and usernames into a listView. The problem is how can I get the comments, usernames and numbers to the BaseAdapter class? Here is my current code
class loadComments extends AsyncTask<JSONObject, String, JSONObject> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
protected JSONObject doInBackground(JSONObject... params) {
JSONObject json2 = CollectComments.collectComments(usernameforcomments, offsetNumber);
return json2;
}
#Override
protected void onPostExecute(JSONObject json2) {
try {
if (json2.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res2 = json2.getString(KEY_SUCCESS);
if(Integer.parseInt(res2) == 1){
l1=(ListView)findViewById(R.id.list);
JSONArray commentArray = json2.getJSONArray(KEY_COMMENT);
String comments[] = new String[commentArray.length()];
for ( int i=0; i<commentArray.length(); i++ ) {
comments[i] = commentArray.getString(i);
}
JSONArray numberArray = json2.getJSONArray(KEY_NUMBER);
String numbers[] = new String[numberArray.length()];
for ( int i=0; i<numberArray.length(); i++ ) {
numbers[i] = numberArray.getString(i);
}
JSONArray usernameArray = json2.getJSONArray(KEY_USERNAME);
String usernames[] = new String[usernameArray.length()];
for ( int i=0; i<usernameArray.length(); i++ ) {
usernames[i] = usernameArray.getString(i);
}
}//end if key is == 1
else{
// Error in registration
registerErrorMsg.setText(json2.getString(KEY_ERROR_MSG));
}//end else
}//end if
} //end try
catch (JSONException e) {
e.printStackTrace();
}//end catch
}
}
new loadComments().execute();
class CreateCommentLists extends BaseAdapter{
Context ctx_invitation;
String[] listComments;
String[] listNumbers;
String[] listUsernames;
public CreateCommentLists(Context ctx_invitation, String[] comments, String[] Numbers, String[] usernames)
{
super();
this.ctx_invitation = ctx_invitation;
listComments = comments;
listNumbers = Numbers;
listUsernames = usernames;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return listComments.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return listComments[position];
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = null;
try
{
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li = (LayoutInflater)ctx_invitation.getSystemService(inflater);
v = li.inflate(R.layout.list_item, null);
TextView commentView = (TextView)v.findViewById(R.id.listComment);
TextView NumbersView = (TextView)v.findViewById(R.id.listNumber);
TextView usernamesView = (TextView)v.findViewById(R.id.listPostedBy);
commentView.setText(listComments[position]);
NumbersView.setText(listNumbers[position]);
usernamesView.setText(listUsernames[position]);
}
catch(Exception e)
{
e.printStackTrace();
}
return v;
}
}
overwrite the values of the adapter you have implemented or add setters for them. Then set the values and make sure you call notifyDatasetChanged on the adapter.
You can either reference the adapter directly if it is a global variable or pass it in the constructor of your AsyncTask
In onPostExecute you can create a new BaseAdapter with the new data and then use setAdapter to set it as the adapter for your ListView. Or, as already said, you can use setters to update data in your current adapter and then notify the ListView that it should redraw itself.
By the very nature of AsyncTask you can update your UI wherever you want in onPreExecution, onProgressUpdate and onPostExecution.
I'm attempting to set the text color in a CustomAdapter class by overriding the View. The code seems to run but the phone screen displays nothing. Any suggestions?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = PreferenceManager.getDefaultSharedPreferences(LogCat.this);
String logLevel = prefs.getString("dirLogCat", "");
setContentView(R.layout.log_cat);
ListView lv1 = (ListView) findViewById(R.id.listView1);
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(this, R.layout.text_list, log);
try {
Process process = Runtime.getRuntime().exec(new String[] {"logcat", "-d"});
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while ((line = bufferedReader.readLine()) != null){
if (line.contains(" " + logLevel + " ")){
//log.add(line);
log.add(line.substring(6, 14) + " " + line.substring(31, line.length()));
}
}
CustomAdapter adapter = new CustomAdapter(log, this, "V");
lv1.setAdapter(arrayAdapter);
adapter.notifyDataSetChanged();
}
catch (IOException e) {}
}
public class CustomAdapter extends BaseAdapter {
private Context ctx;
CustomAdapter (ArrayList<String> data, Context context, String log) {
this.ctx = context;
this.getView(0, new View(context), null);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflator = (LayoutInflater)ctx.getSystemService(LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.text_list, null);
TextView textView = (TextView) v.findViewById(R.id.logText);
textView.setTextColor(Color.CYAN);
return textView;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
}
}
EDIT:
This did it:
public class CustomAdapter extends BaseAdapter {
private Context ctx;
private ArrayList<String> children;
CustomAdapter (ArrayList<String> data, Context context, String log) {
this.ctx = context;
System.out.println("Cyan1");
this.children = data;
this.getView(0, new View(context), null);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflator = (LayoutInflater)ctx.getSystemService(LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.text_list, null);
TextView textView = (TextView) v.findViewById(R.id.logText);
System.out.println("Cyan");
textView.setTextColor(Color.CYAN);
for(int i = 0; i < log.size(); i++){
textView.setText(children.get(i));
}
return textView;
}
You're setting the wrong adapter in the list?
CustomAdapter adapter = new CustomAdapter(log, this, "V");
lv1.setAdapter(arrayAdapter); //<---- arrayAdapter instead of adapter?
adapter.notifyDataSetChanged();
I am working on android projects. In my application I am getting the data from php webservice. I added my data to different arraylists and set them to listadapter. But my problem is it is taking very long time to display the data in list. Hence now I want to display first 10 items and want to keep a loadmore button at the bottom of the screen. Once the load more button is clicked the next 10 items need to display. Please can anybody help me in this regard. I would really appreciate for this help.
Thank you in advance.
Code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
Longop op = new Longop();
op.execute("");
}
public void loadSomeDummyData() {
try {
response = CustomHttpClient
.executeHttpPost(
"http://website.com/folder/testfile.php",
postParameters);
for (int i = 1; i < arr1.length - 1; i++) {
id.add(new String(arr[0]));
name.add(new String(arr[1]));
dateofbirth.add(new String(arr[2]));
status.add(new String(arr[3]));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private class Longop extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
loadSomeDummyData();
return "Executed";
}
#Override
protected void onPostExecute(String result) {
mdialog.dismiss();
myListView.setAdapter(new MyArrayAdapter(Sample.this,
R.layout.list, id, name, dateofbirth,
status));
}
#Override
protected void onPreExecute() {
mdialog = ProgressDialog.show(Sample.this, "Please wait...",
"Retrieving data ...", true);
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
private class MyArrayAdapter extends ArrayAdapter<String> {
// this list hold the data that we will see in listview
private List<String> myData = new ArrayList<String>();
private List<String> myData1 = new ArrayList<String>();
private List<String> myData2 = new ArrayList<String>();
private List<String> myData3 = new ArrayList<String>();
public MyArrayAdapter(Context context, int textViewResourceId,
List<String> objects, List<String> objects1,
List<String> objects2, List<String> objects3) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
context = getContext();
myData = objects;
myData1 = objects1;
myData2 = objects2;
myData3 = objects3;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list, null);
// Log.d(EKSI, "Getting the inflater from the system context");
}
String sid = myData.get(position);
String sname = myData1.get(position);
String dob = myData2.get(position);
String sstatus = myData3.get(position);
TextView entryTextView = (TextView) v.findViewById(R.id.id1);
entryTextView.setText(sid);
TextView entryTextView1 = (TextView) v
.findViewById(R.id.id2);
entryTextView1.setText(sname);
TextView entryTextView2 = (TextView) v
.findViewById(R.id.id3);
entryTextView2.setText(dob);
TextView entryTextView3 = (TextView) v
.findViewById(R.id.id4);
entryTextView3.setText(sstatus);
return v;
}
}
You could also use this lib
https://github.com/chrisbanes/Android-PullToRefresh.
I implement this function not base ListView that can do this;
Custom loading view,override onDraw menthod
Add loading view at the end of LinearLayout view. When loading view is show, it should call some methods to get data from server by HTTP.
you just need to inflate an xml in
lstView.addFooterView(R.layout.footer);
and handle onclick of the button residing in footer