private class getArticles extends AsyncTask<Void, Void, Void> {
String url;
getArticles(String paramUrl) {
this.url = paramUrl;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(App.this);
mProgressDialog.setMessage("Učitavanje artikala...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
arraylist = new ArrayList<>();
try {
Document document = Jsoup.connect(url).get();
Elements els = document.select("ul.category3 > li");
for (Element el : els) {
HashMap<String, String> map = new HashMap<>();
Elements slika = el.select("div.category3-image > a > img");
Elements naslov = el.select("div.category3-text > a.main-headline");
Element datum_noformat = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li").first();
Element datum = datum_noformat.html(datum_noformat.html().replaceAll("Posted ", ""));
Elements desc = el.select("div.category3-text > p");
Elements link = el.select("div.category3-text > a.main-headline");
Element br_kom = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li.comments-icon").first();
map.put("naslov", naslov.text());
map.put("datum", datum.text());
map.put("desc", desc.text());
map.put("ikona", slika.attr("src"));
map.put("link", link.attr("abs:href"));
map.put("brkom", br_kom.text());
arraylist.add(map);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
adapter = new ArtikliAdapter(App.this, arraylist);
listview.setAdapter(adapter);
mProgressDialog.dismiss();
}
I searched for a lot of codes for onlistview scrolling, but didn't know how to implement it. The problem is, when I call my asynctask, I have an url param,
like new getArticles("http://example.com").execute();
I want to implement an onscrolllistener, but it goes like this, my param is usually set to: http://www.example.com/category/categoryname/, so the second page goes like http://www.example.com/category/categoryname/page/2/, the third one goes http://www.example.com/category/categoryname/page/3/ and so on. Each page has got 7 items that need to be parsed.
How could I implement onscrolllistener, because of the url param?
Thanks in advance.
Base on this link, I have written following solution to add elements ( 30 elements at a time, i.e page size = 30) to listview asynchronously.
Create a class named EndlessListView as follows:
public class EndlessListView extends ListView implements OnScrollListener {
private View footer;
private boolean isLoading;
private EndlessListener listener;// listner
private EndlessAdapter endlessAdapter;// adapter.
private int maxNoOfElement;
public EndlessListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setOnScrollListener(this);
}
public EndlessListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnScrollListener(this);
}
public EndlessListView(Context context) {
super(context);
this.setOnScrollListener(this);
}
public void setListener(EndlessListener listener) {
this.listener = listener;
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() == null)
return;
if (getAdapter().getCount() == 0 || getAdapter().getCount() <= 5)
return;
int l = visibleItemCount + firstVisibleItem;
if (l >= totalItemCount && !isLoading) {
// It is time to add new data. We call the listener
Log.e("LOAD", "DATA");
isLoading = true;
listener.loadData();
}
}
public void setMaxElemnt(int maxNoOfElement) {
this.maxNoOfElement = maxNoOfElement;
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void setLoadingView(int resId) {
LayoutInflater inflater = (LayoutInflater) super.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
footer = (View) inflater.inflate(resId, null);
this.addFooterView(footer);
}
public void setAdapter(EndlessAdapter adapter) {
super.setAdapter(adapter);
this.endlessAdapter = adapter;
}
public void addNewData(List<Integer> data) {
endlessAdapter.setData(data);
endlessAdapter.notifyDataSetChanged();
isLoading = false;
}
public static interface EndlessListener {
public void loadData();
}
}
After this we have to create the adapter for it,called
EndlessAdapter
public class EndlessAdapter extends BaseAdapter {
private List<Integer> mIntegers;
private Context context;
public EndlessAdapter(Context context) {
this.context = context;
}
public void setData(List<Integer> mIntegers) {
this.mIntegers = mIntegers;
}
#Override
public int getCount() {
if (mIntegers == null)
return 0;
return mIntegers.size();
}
#Override
public Integer getItem(int index) {
if (mIntegers == null) {
return null;
} else {
return mIntegers.get(index);
}
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
class ViewHolder {
TextView textView;
}
#Override
public View getView(int index, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = ((LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.rows, viewGroup, false);
holder.textView = (TextView) view.findViewById(R.id.mtext);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(getItem(index) + "");
return view;
}
}
Now in xml of the activity we could use EndlessListView(in com.example.stackoverflow package) as follows :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.stackoverflow.EndlessListView
android:id="#+id/endlessListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
After this step we need to make following change in the MainActivity
public class MainActivity extends Activity implements EndlessListener {
private EndlessAdapter adapter;
private EndlessListView endlessListView;
private List<Integer> data;
private int gStartIndex = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
endlessListView = (EndlessListView) findViewById(R.id.endlessListView);
adapter = new EndlessAdapter(this);
data = new ArrayList<Integer>();
endlessListView.setLoadingView(R.layout.footer);
// endlessListView.showFooter();
endlessListView.setListener(this);
endlessListView.setAdapter(adapter);
gStartIndex = 0;
fillData(gStartIndex);
}
private void fillData(int startIndex) {
new AsyncLoadData().execute(startIndex);
}
#Override
public void loadData() {
fillData(gStartIndex);
}
private class AsyncLoadData extends AsyncTask<Integer, Integer, Void> {
#Override
protected Void doInBackground(Integer... params) {
int gendIndex = params[0] + 30;
gStartIndex = gendIndex;
/***
* Here you could add your n/w code. To simulate the n/w comm. i am
* adding elements to list and making it sleep for few sec.
* */
for (int i = params[0]; i < gendIndex; i++) {
publishProgress(i);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
data.add(values[0]);
}
#Override
protected void onPostExecute(Void result) {
endlessListView.addNewData(data);
}
}
}
This custom ScrollListView that I just found has OnBottomReachedListener which you can implement from your Activity or Fragment and receive events when user hits the bottom of the page. You would also need to track the current page and when bottom is hit to download the next page. The latest data should be added to your existing ArrayList and you should call notifyDataSetChanged() on your adapter so ListView can render the new data. You don't have to create new adapter, you just need to update the data source which is your ArrayList.
If you support orientation change you would must to save in onSaveInstanceState() your current page number so when Activity or Fragment is recreated it can continue from correct page. And you would have to keep the ArrayList data source safe of configuration changes because you don't want to downloaded it again. I would suggest using the Fragment with setRetainInstance() set to true to persist ArrayList.
Here is my custom code for keeping data around using RetainFragment:
/**
* A simple non-UI Fragment that stores a single Object
* and is retained over configuration changes.
*/
public class RetainFragment<E extends Object> extends Fragment {
/** Object for retaining. */
private E mObject;
/**
* Empty constructor as per the Fragment documentation
*/
public RetainFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make sure this Fragment is retained over a configuration change
setRetainInstance(true);
}
/**
* Store a single object in this Fragment.
*
* #param object The object to store
*/
public void setObject(E object) {
mObject = object;
}
/**
* Get the stored object.
*
* #return The stored object
*/
public E getObject() {
return mObject;
}
}
Example of RetainFragment usage in your Activity:
FragmentManager fm = getFragmentManager();
mRetainFragment = (RetainFragment<ArrayList>) fm.findFragmentByTag(RETAIN_FRAG);
if (mRetainFragment == null) {
mRetainFragment = new RetainFragment<>();
mRetainFragment.setObject(new ArrayList());
fm.beginTransaction().add(mRetainFragment, RETAIN_FRAG).commit();
}
ArrayList yourArrayList = mRetainFragment.getObject();
// Now your ArrayList is saved accrossed configuration changes
here what you want fist add onscrolllistner to listview
boolean loading_flage = false;
yourlistview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(
AbsListView view,
int scrollState) {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView view,
int firstVisibleItem,
int visibleItemCount,
int totalItemCount) {
final int lastItem = firstVisibleItem
+ visibleItemCount;
if ((lastItem == totalItemCount)
& loading_flage == false) {
//this to prevent the list to make more than one request in time
loading_flage = true;
//you can put the index for your next page here
loadMore(int page);
}
}
});
and then in loading more after loading the page set the loading with false and parse the data add it to the data that you aleardy have
//notify the adapter
adapter.notifyDataSetChanged();
loading_flage = false;
You can achieve by adding the scrolllistener on listview and check condition if list last visible item is last in ArrayList then call the asynctask with incremented page number and update the listview,mean while add the view on listview and after getting the result from server remove the loading more view from the listview like this -
AndroidListViewLoadMoreActivity.java
public class AndroidListViewLoadMoreActivity extends Activity {
ArrayList<Country> countryList;
MyCustomAdapter dataAdapter = null;
int page = 0;
boolean loadingMore = false;
View loadMoreView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.listView1);
loadMoreView = ((LayoutInflater)this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.loadmore, null, false);
listView.addFooterView(loadMoreView);
//create an ArrayAdaptar from the String Array
countryList = new ArrayList<Country>();
dataAdapter = new MyCustomAdapter(this,
R.layout.country_info, countryList);
listView.setAdapter(dataAdapter);
//enables filtering for the contents of the given ListView
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Country country = (Country) parent.getItemAtPosition(position);
Toast.makeText(getApplicationContext(),
country.getCode(), Toast.LENGTH_SHORT).show();
}
});
listView.setOnScrollListener(new OnScrollListener(){
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if((lastInScreen == totalItemCount) && !(loadingMore)){
String url = "http://10.0.2.2:8080/CountryWebService" +
"/CountryServlet";
grabURL(url);
}
}
});
String url = "http://example.com";
grabURL(url);
}
public void grabURL(String url) {
Log.v("Android Spinner JSON Data Activity", url);
new GrabURL().execute(url);
}
private class GrabURL extends AsyncTask<String, Void, String> {
private static final int REGISTRATION_TIMEOUT = 3 * 1000;
private static final int WAIT_TIMEOUT = 30 * 1000;
private final HttpClient httpclient = new DefaultHttpClient();
final HttpParams params = httpclient.getParams();
HttpResponse response;
private String content = null;
private boolean error = false;
private ProgressDialog dialog =
new ProgressDialog(AndroidListViewLoadMoreActivity.this);
protected void onPreExecute() {
dialog.setMessage("Getting your data... Please wait...");
dialog.show();
}
protected String doInBackground(String... urls) {
String URL = null;
loadingMore = true;
try {
URL = urls[0];
HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT);
ConnManagerParams.setTimeout(params, WAIT_TIMEOUT);
HttpPost httpPost = new HttpPost(URL);
//add name value pair for the country code
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("page",String.valueOf(page)));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = httpclient.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
content = out.toString();
} else{
//Closes the connection.
Log.w("HTTP1:",statusLine.getReasonPhrase());
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.w("HTTP2:",e );
content = e.getMessage();
error = true;
cancel(true);
} catch (IOException e) {
Log.w("HTTP3:",e );
content = e.getMessage();
error = true;
cancel(true);
}catch (Exception e) {
Log.w("HTTP4:",e );
content = e.getMessage();
error = true;
cancel(true);
}
return content;
}
protected void onCancelled() {
dialog.dismiss();
Toast toast = Toast.makeText(AndroidListViewLoadMoreActivity.this,
"Error connecting to Server", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
protected void onPostExecute(String content) {
dialog.dismiss();
Toast toast;
if (error) {
toast = Toast.makeText(AndroidListViewLoadMoreActivity.this,
content, Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
} else {
displayCountryList(content);
}
}
}
private void displayCountryList(String response){
JSONObject responseObj = null;
try {
Gson gson = new Gson();
responseObj = new JSONObject(response);
JSONArray countryListObj = responseObj.getJSONArray("countryList");
//countryList = new ArrayList<Country>();
if(countryListObj.length() == 0){
ListView listView = (ListView) findViewById(R.id.listView1);
listView.removeFooterView(loadMoreView);
}
else {
for (int i=0; i<countryListObj.length(); i++){
//get the country information JSON object
String countryInfo = countryListObj.getJSONObject(i).toString();
//create java object from the JSON object
Country country = gson.fromJson(countryInfo, Country.class);
//add to country array list
countryList.add(country);
dataAdapter.add(country);
}
page++;
dataAdapter.notifyDataSetChanged();
loadingMore = false;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Make MyCustomAdapter.java as adapter
private class MyCustomAdapter extends ArrayAdapter<Country> {
private ArrayList<Country> countryList;
public MyCustomAdapter(Context context, int textViewResourceId,
ArrayList<Country> countryList) {
super(context, textViewResourceId, countryList);
this.countryList = new ArrayList<Country>();
this.countryList.addAll(countryList);
}
private class ViewHolder {
TextView code;
TextView name;
TextView continent;
TextView region;
}
public void add(Country country){
Log.v("AddView", country.getCode());
this.countryList.add(country);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.country_info, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.code);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.continent = (TextView) convertView.findViewById(R.id.continent);
holder.region = (TextView) convertView.findViewById(R.id.region);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Country country = this.countryList.get(position);
holder.code.setText(country.getCode());
holder.name.setText(country.getName());
holder.continent.setText(country.getContinent());
holder.region.setText(country.getRegion());
return convertView;
}
}
}
Create Country.Java as pojo -
public class Country {
String code = null;
String name = null;
String continent = null;
String region = null;
Double lifeExpectancy = null;
Double gnp = null;
Double surfaceArea = null;
int population = 0;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContinent() {
return continent;
}
public void setContinent(String continent) {
this.continent = continent;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public Double getLifeExpectancy() {
return lifeExpectancy;
}
public void setLifeExpectancy(Double lifeExpectancy) {
this.lifeExpectancy = lifeExpectancy;
}
public Double getGnp() {
return gnp;
}
public void setGnp(Double gnp) {
this.gnp = gnp;
}
public Double getSurfaceArea() {
return surfaceArea;
}
public void setSurfaceArea(Double surfaceArea) {
this.surfaceArea = surfaceArea;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
}
Create main.xml for main layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:padding="10dp"
android:text="#string/some_text" android:textSize="20sp" />
<ListView android:id="#+id/listView1" android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Create country_info.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dip" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Code: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/textView1"
android:text="Name: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView2"
android:layout_below="#+id/textView2"
android:text="Continent: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView3"
android:layout_below="#+id/textView3"
android:text="Region: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/continent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView3"
android:layout_alignBottom="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:text="TextView" />
<TextView
android:id="#+id/region"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView4"
android:layout_alignBottom="#+id/textView4"
android:layout_alignLeft="#+id/continent"
android:text="TextView" />
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:text="TextView" />
<TextView
android:id="#+id/code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView2"
android:layout_alignLeft="#+id/name"
android:text="TextView" />
</RelativeLayout>
Footer View Text - loadmore.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:padding="3dp"
android:layout_height="fill_parent">
<TextView
android:id="#id/android:empty"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:padding="5dp"
android:text="Loading more data..."/>
</LinearLayout>
Don't forget to mention internet permission with -
<uses-permission android:name="android.permission.INTERNET" />
First, you need a OnScrollListener method like this:
private OnScrollListener onScrollListener() {
return new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int threshold = 1;
int count = listView.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (listView.getLastVisiblePosition() >= count - threshold && pageCount < 2) {
Log.i(TAG, "loading more data");
// Execute LoadMoreDataTask AsyncTask
//It reached ListView bottom
getDataFromUrl(url_page2);
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
}
};
}
set List View scroll listener by listView.setOnScrollListener(onScrollListener());
I have a full tutorial post HERE! You can visit it!
Related
I'm having difficulty in downloading footballing data from an (http://www.football-data.org). I am trying to download the English Premier League Table by creating a new Standing object for each team and adding them to an ArrayList.
I've set up my parser class, adapter class and my view.
The error I am getting is :
org.json.JSONException: org.json.JSONException: Value {"_links":{"self":{"href":"http:\/\/api.football-data.org\/v1\/soccerseasons\/426\/leagueTable\/?matchday=37"},"soccerseason":{"href":"http:\/\/api.football-data.org\/v1\/soccerseasons\/426"}},"leagueCaption":"Premier League 2016\/17","matchday":37,"standing":[{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/61"}},"position":1,"teamName":"Chelsea FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/5\/5c\/Chelsea_crest.svg","playedGames":36,"points":87,"goals":76,"goalsAgainst":29,"goalDifference":47,"wins":28,"draws":3,"losses":5,"home":{"goals":46,"goalsAgainst":13,"wins":15,"draws":0,"losses":2},"away":{"goals":30,"goalsAgainst":16,"wins":13,"draws":3,"losses":3}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/73"}},"position":2,"teamName":"Tottenham Hotspur FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/b\/b4\/Tottenham_Hotspur.svg","playedGames":35,"points":77,"goals":71,"goalsAgainst":23,"goalDifference":48,"wins":23,"draws":8,"losses":4,"home":{"goals":45,"goalsAgainst":8,"wins":16,"draws":2,"losses":0},"away":{"goals":26,"goalsAgainst":15,"wins":7,"draws":6,"losses":4}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/65"}},"position":3,"teamName":"Manchester City FC","crestURI":"https:\/\/upload.wikimedia.org\/wikipedia\/en\/e\/eb\/Manchester_City_FC_badge.svg","playedGames":36,"points":72,"goals":72,"goalsAgainst":38,"goalDifference":34,"wins":21,"draws":9,"losses":6,"home":{"goals":34,"goalsAgainst":16,"wins":10,"draws":7,"losses":1},"away":{"goals":38,"goalsAgainst":22,"wins":11,"draws":2,"losses":5}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/64"}},"position":4,"teamName":"Liverpool FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/0\/0a\/FC_Liverpool.svg","playedGames":36,"points":70,"goals":71,"goalsAgainst":42,"goalDifference":29,"wins":20,"draws":10,"losses":6,"home":{"goals":42,"goalsAgainst":18,"wins":11,"draws":5,"losses":2},"away":{"goals":29,"goalsAgainst":24,"wins":9,"draws":5,"losses":4}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/57"}},"position":5,"teamName":"Arsenal FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/en\/5\/53\/Arsenal_FC.svg","playedGames":35,"points":66,"goals":68,"goalsAgainst":42,"goalDifference":26,"wins":20,"draws":6,"losses":9,"home":{"goals":34,"goalsAgainst":15,"wins":12,"draws":3,"losses":2},"away":{"goals":34,"goalsAgainst":27,"wins":8,"draws":3,"losses":7}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/66"}},"position":6,"teamName":"Manchester United FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/d\/da\/Manchester_United_FC.svg","playedGames":35,"points":65,"goals":51,"goalsAgainst":27,"goalDifference":24,"wins":17,"draws":14,"losses":4,"home":{"goals":24,"goalsAgainst":12,"wins":7,"draws":10,"losses":1},"away":{"goals":27,"goalsAgainst":15,"wins":10,"draws":4,"losses":3}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/62"}},"position":7,"teamName":"Everton FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/f\/f9\/Everton_FC.svg","playedGames":37,"points":61,"goals":61,"goalsAgainst":41,"goalDifference":20,"wins":17,"draws":10,"losses":10,"home":{"goals":42,"goalsAgainst":16,"wins":13,"draws":4,"losses":2},"away":{"goals":19,"goalsAgainst":25,"wins":4,"draws":6,"losses":8}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/74"}},"position":8,"teamName":"West Bromwich Albion FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/8\/8b\/West_Bromwich_Albion.svg","playedGames":36,"points":45,"goals":41,"goalsAgainst":46,"goalDifference":-5,"wins":12,"draws":9,"losses":15,"home":{"goals":27,"goalsAgainst":22,"wins":9,"draws":2,"losses":8},"away":{"goals":14,"goalsAgainst":24,"wins":3,"draws":7,"losses":7}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/1044"}},"position":9,"teamName":"AFC Bournemouth","crestURI":"https:\/
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at org.json.JSONArray.<init>(JSONArray.java:96)
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at org.json.JSONArray.<init>(JSONArray.java:108)
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at com.example.oisin.premierleaguesocial.Utilities.JSONParser.parse(JSONParser.java:75)
05-13 15:39:24.799 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at com.example.oisin.premierleaguesocial.Utilities.JSONParser.doInBackground(JSONParser.java:56)
05-13 15:39:24.799 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at com.example.oisin.premierleaguesocial.Utilities.JSONParser.doInBackground(JSONParser.java:27)
I've been trying to resolve the issue for a few hours, but can't fix it. I think I've set up my data types correctly. I decided to only try to get the Integer data types at first for the sake of simplicity.
Any help would be very much appreciated. Thank you.
public class JSONParser extends AsyncTask<Void, Void, Boolean> {
private Context c;
private String jsonData;
private RecyclerView rv;
private ProgressDialog pd;
private ArrayList<Standing> mLeagueTable = new ArrayList<>();
public JSONParser(Context c, String jsonData, RecyclerView rv) {
this.c = c;
this.jsonData = jsonData;
this.rv = rv;
}
#Override
protected void onPreExecute () {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Parse");
pd.setMessage("Parsing..Please Wait");
pd.show();
}
#Override
protected Boolean doInBackground (Void...params){
return parse();
}
#Override
protected void onPostExecute (Boolean isParsed){
super.onPostExecute(isParsed);
pd.dismiss(); //Dismiss progress dialog.
if (isParsed) {
//BIND
rv.setAdapter(new TableAdapter(c, mLeagueTable)); //Pass in instance of adapter.
} else {
Toast.makeText(c, "Unable to Parse check your Log Output", Toast.LENGTH_SHORT).show();
}
}
private Boolean parse() {
try {
//JSONArray ja = new JSONArray(jsonData);
JSONArray ja = new JSONArray("standing");
JSONObject jo; //declare json OBJECT
mLeagueTable.clear(); //Clears the ArrayList.
Standing table; //Declare a table
for (int i = 0; i < ja.length(); i++) //iterating in JSONArray
{
jo = ja.getJSONObject(i);
int position = ja.getInt(Integer.parseInt("position"));
int points = ja.getInt(Integer.parseInt("points"));
int playedGames = ja.getInt(Integer.parseInt("playedGames"));
int goals = ja.getInt(Integer.parseInt("goals"));
int goalsAgainst = ja.getInt(Integer.parseInt("goalsAgainst"));
int goalDifference = ja.getInt(Integer.parseInt("goalDifference"));
table = new Standing(); //Create a new "User" object.
table.setPosition(position);
table.setPoints(points);
table.setPlayedGames(playedGames);
table.setGoals(goals);
table.setGoalsAgainst(goalsAgainst);
table.setGoalDifference(goalDifference);
mLeagueTable.add(table); //Add new Standing object to ArrayList mLeagueTable.
}
return true;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
}
public class JSONDownloader extends AsyncTask<Void, Void, String> {
Context c;
String jsonURL;
RecyclerView rv;
ProgressDialog pd;
public JSONDownloader(Context c, String jsonURL, RecyclerView rv) {
this.c = c;
this.jsonURL = jsonURL;
this.rv = rv;
}
#Override
protected void onPreExecute() { //CALLED just before data is downloaded.
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Download JSON");
pd.setMessage("Downloading.... Please Wait!");
pd.show();
}
#Override
protected String doInBackground(Void... voids) {
return download();
}
#Override
protected void onPostExecute(String jsonData) {
super.onPostExecute(jsonData);
pd.dismiss();
if (jsonData.startsWith("Error"))
{
String error = jsonData;
Toast.makeText(c, error, Toast.LENGTH_SHORT).show();
} else {
//PARSER
new JSONParser(c, jsonData, rv).execute();
}
}
private String download() {
Object connection = Connector.connect(jsonURL);
if (connection.toString().startsWith("Error")) {
return connection.toString();
}
try {
HttpURLConnection con = (HttpURLConnection) connection; //Cast connection to HTTPConnection
if (con.getResponseCode() == con.HTTP_OK) {
//GET INPUT FROM STREAM
InputStream is = new BufferedInputStream(con.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer jsonData = new StringBuffer();
// READ
while ((line = br.readLine()) != null) {
jsonData.append(line + "\n");
}
//CLOSE RESOURCES
br.close();
is.close();
//RETURN JSON
return jsonData.toString();
} else {
return "Error " + con.getResponseMessage();
}
} catch (IOException e) {
e.printStackTrace();
return "Error " + e.getMessage();
}
}
}
public class MainActivity extends AppCompatActivity {
String jsonURL = "http://api.football-data.org/v1/soccerseasons/426/leagueTable";
public static final String TAG = "MainActivity";
//FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
private RecyclerView rv;
/*private ArrayList<Standing> mLeagueTable = new ArrayList<>(); //Initalise m
private TableAdapter mTableAdapter = new TableAdapter(mLeagueTable, this); */
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_table);
//Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
rv = (RecyclerView) findViewById(R.id.rv);
if (rv != null) {
rv.setLayoutManager(new LinearLayoutManager(this));
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); //Initialze FAB
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new JSONDownloader(MainActivity.this, jsonURL, rv).execute();
}
});
}
}
public class TableAdapter extends RecyclerView.Adapter<MyViewHolder>{
private ArrayList<Standing> mLeagueTable;
private Context c;
public TableAdapter(Context c, ArrayList<Standing> mLeagueTable) {
this.c = c;
this.mLeagueTable = mLeagueTable;
} //Constructor
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.tableitem, parent, false); //Inlfate the League Table model view.
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) { //BINDS THE data to the appropriote View
Standing s = mLeagueTable.get(position);
final int teamPosition = s.getPosition();
final String teamName = s.getTeamName();
final int playedGames = s.getPlayedGames();
final int goals = s.getGoals();
final int goalsAgainst = s.getGoalsAgainst();
final int goalDifference = s.getGoalDifference();
final int points = s.getPoints();
//holder.teamNameTxt.setText(teamName);
holder.teamPositionTxt.setText(teamPosition);
holder.playedGamesTxt.setText(playedGames);
//holder.teamImage.setImageResource(s.getTeamImage());
holder.goalsTxt.setText(goals);
holder.goalsAgainstTxt.setText(goalsAgainst);
holder.goalDifferenceTxt.setText(goalDifference);
holder.pointsTxt.setText(points);
// holder.wins.setText(s.getWins());
//holder.draws.setText(s.getDraws());
//holder.losses.setText(s.getLosses());
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(int pos) {
openActivity(teamPosition, playedGames, goals, goalsAgainst, goalDifference, points);
}
});
}
#Override
public int getItemCount() {return mLeagueTable.size();}
////open Activity
private void openActivity(int...details)
{
Intent i = new Intent(c, TableActivity.class);
i.putExtra("POSITION_KEY", details[0]);
//i.putExtra("TEAMNAME_KEY", details[1]);
i.putExtra("POINTS_KEY", details[2]);
i.putExtra("PLAYEDGAMES_KEY", details[3]);
i.putExtra("GOALS_KEY", details[4]);
i.putExtra("GOALSAGAINST_KEY", details[5]);
i.putExtra("GOALDIFFERENCE_KEY", details[6]);
c.startActivity(i);
}
}
tableitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/teamPositionTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/teamNameTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/pointsTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text"
android:textStyle="bold" />
<TextView
android:id="#+id/playedGamesTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/goalsTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/goalsAgainstTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/goalDifferenceTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
</LinearLayout>
1. Create a JSONObject from string jsonData.
2. Get JSONArray (standing) from JSONObject by using jsonObj.getJSONArray("standing").
3. Inside for loop, get int values from JsonObject using jo.getInt() instead of ja.getInt().
Here is the working code:
private Boolean parse() {
try {
JSONObject jsonObj = new JSONObject(jsonData);
JSONArray ja = jsonObj.getJSONArray("standing");
mLeagueTable.clear(); //Clears the ArrayList.
for (int i = 0; i < ja.length(); i++) //iterating in JSONArray
{
JSONObject jo = ja.getJSONObject(i);
int position = jo.getInt(Integer.parseInt("position"));
int points = jo.getInt(Integer.parseInt("points"));
int playedGames = jo.getInt(Integer.parseInt("playedGames"));
int goals = jo.getInt(Integer.parseInt("goals"));
int goalsAgainst = jo.getInt(Integer.parseInt("goalsAgainst"));
int goalDifference = jo.getInt(Integer.parseInt("goalDifference"));
Standing table = new Standing(); //Create a new "User" object.
table.setPosition(position);
table.setPoints(points);
table.setPlayedGames(playedGames);
table.setGoals(goals);
table.setGoalsAgainst(goalsAgainst);
table.setGoalDifference(goalDifference);
mLeagueTable.add(table); //Add new Standing object to ArrayList mLeagueTable.
}
return true;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
Hope this will work~
Change
JSONArray ja = new JSONArray("standing");
for
JSONObject ja = new JSONObject(jsonData);
JSONObject jo = ja.getJSONObject("soccerseason");
The information is in jo, and now you can extract each field following the right structure of the JSONObject
I would like to populate my Listview using a loop, I have recently attempted to populate it in a very inefficient way by making multiple calls for the data from SQL. When I realized just how inefficient it was I began to pull the data from the server in one go by making use of arrays. I am having trouble changing my code for this to work.
What I need to do is find a way of looping through the below array of JSONArrays (Which is not the hard part for me), but to do so I need to have my GetSocietyDataASyncTask return the above array and find a way of passing it to the OnCreate/done method in SocietySearch.java (Alot of the Society objects in my code can be ignored and somehow replaced with List societies)
Now I believe that I have included all of the relevant code but if you need to see anything else please do not hesitate to ask me.
The data that is received by Java from my database looks like this:
[{"society_id":1,"name":"TestName1","email":"Test#email1","description":"TestDes1"},
{"society_id":2,"name":"TestName2","email":"Test#email2","description":"TestDes2"}]
SocietySearch Class:
public class SocietySearch extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_society_search);
Society society = new Society(-1, null, null, null);
ServerRequests serverRequest1 = new ServerRequests(SocietySearch.this);
serverRequest1.GetSocietyDataAsyncTask(society, new GetSocietyCallback() {
#Override
public void done(final Society returnedSociety) {
ListView lv = (ListView) findViewById(R.id.ListView);
List<ListViewItem> items = new ArrayList<>();
items.add(new ListViewItem() {{
ThumbnailResource = R.drawable.test;
Title = returnedSociety.socName;
Subtitle = returnedSociety.socDes;
}});
CustomListViewAdapter adapter = new CustomListViewAdapter(SocietySearch.this, items);
lv.setAdapter(adapter);
}
});
}
class ListViewItem {
public int ThumbnailResource;
public String Title;
public String Subtitle;
}
Relevant Part Of ServerRequests Class:
public class getSocietyDataAsyncTask extends AsyncTask<Void, Void, Society> {
Society society;
GetSocietyCallback societyCallback;
public getSocietyDataAsyncTask(Society society, GetSocietyCallback societyCallback) {
this.society = society;
this.societyCallback = societyCallback;
}
#Override
protected Society doInBackground(Void... params) {
BufferedReader reader = null;
Society returnedSociety = null;
List<Society> societies = new ArrayList<>();
try {
URL url = new URL(SERVER_ADDRESS + "/getsocietydata.php");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(CONNECTION_TIMEOUT);
con.setReadTimeout(CONNECTION_TIMEOUT);
con.setRequestMethod("POST");
con.setDoOutput(true);
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = reader.readLine()) != null) { //Read until there is something available
sb.append(line + "\n"); //Read and save line by line
}
line = sb.toString(); //Saving complete data received in string
//Check values received in Logcat
Log.i("custom_check", "The values received in the store part are as follows:");
Log.i("custom_check", line);
JSONArray ja = new JSONArray(line);
if (ja != null && ja.length() == 0) {
returnedSociety = null;
} else {
for (int i = 0; i <ja.length(); i++) {
JSONObject json = ja.optJSONObject(i);
//Storing each Json in a variable
int society_id = json.getInt("society_id");
String socName = json.getString("name");
String socEmail = json.getString("email");
String socDes = json.getString("description");
returnedSociety = new Society(society_id, socName, socEmail, socDes);
societies.add(returnedSociety);
}
return returnedSociety;
}
} catch (Exception e) {
e.printStackTrace();
Log.d("Sample", "Error has occurred!\n" + e.toString());
}
finally {
if (reader != null) {
try {
reader.close(); //Closing the
} catch (IOException e) {
e.printStackTrace();
}
}
}
return returnedSociety;
}
#Override
protected void onPostExecute(Society returnedSociety) {
super.onPostExecute(returnedSociety);
progressDialog.dismiss();
societyCallback.done(returnedSociety);
}
}
CustomListViewAdapter.java:
public class CustomListViewAdapter extends BaseAdapter {
LayoutInflater inflater;
List<SocietySearch.ListViewItem> items;
public CustomListViewAdapter(Activity context, List<SocietySearch.ListViewItem> items) {
super();
this.items = items;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
//Auto-generated method stub
return items.size(); // TODO Maybe this can be my sql count?
}
#Override
public Object getItem(int position) {
//Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
//Auto-generated method stub
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
//Auto-generated method stub
ListViewItem item = items.get(position);
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.item_row, null);
ImageView test = (ImageView) vi.findViewById(R.id.imgThumbnail);
TextView txtTitle = (TextView) vi.findViewById(R.id.txtTitle);
TextView txtSubTitle = (TextView) vi.findViewById(R.id.txtSubTitle);
test.setImageResource(item.ThumbnailResource);
txtTitle.setText(item.Title);
txtSubTitle.setText(item.Subtitle);
return vi;
}
}
ListView Layour file (item_row.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dip">
<ImageView
android:id="#+id/imgThumbnail"
android:layout_width="78dip"
android:layout_height="78dip"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="-3dip"
android:scaleType="centerInside"></ImageView>
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:layout_toRightOf="#+id/imgThumbnail"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceLarge"></TextView>
<TextView
android:id="#+id/txtSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtTitle"
android:layout_marginLeft="6dip"
android:layout_marginTop="3dip"
android:layout_toRightOf="#+id/imgThumbnail"
android:text="TextView"></TextView>
</RelativeLayout>
Take a look at ArrayAdapter and specifically #notifyDataSetChanged. (notifyDataSetChanged example). You can setup the ListView in #onCreate like you have and store off a reference to the underlying Adapter. Initially the Adapter will be empty, but when data comes in simply add it to the Adapter and call #notifyDataSetChanged as guided in the example.
I am working on an Android project in which I have to display some images in a list. For this, I am using an Adapter. I don't see any errors when I run the code, but no image is displayed. Also, I have set an onClickListener, and a Log.d inside it. But the Log.d is not displayed. What am I doing wrong?
public class OtherUsers extends Activity {
private PersonServiceImpl personService = new PersonServiceImpl();
private static volatile List<RestPerson> restPersonList = new ArrayList<>();
public static final String firstName = "firstname";
public static final String userImage = "userimage";
static final String userId = "0";
ListView listView;
UserAdapter userAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.displayuserlist);
restPersonList = this.personService.getOtherUsers();
ArrayList<HashMap<String, String>> usersArrayHashList = new ArrayList<>();
for (RestPerson restPerson : restPersonList) {
HashMap<String, String> restDisplay = new HashMap<>();
restDisplay.put(userId, String.valueOf(restPerson.getUserId()));
restDisplay.put(firstName, restPerson.getFirstName());
restDisplay.put(userImage, restPerson.getProfilePhoto());
usersArrayHashList.add(restDisplay);
}
listView = (ListView) findViewById(R.id.usersdisplaylist);
userAdapter = new UserAdapter(this, usersArrayHashList);
listView.setAdapter(userAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.d("Item", "wasclicked");
Long userid = restPersonList.get(position).getUserId();
Log.d("Userid is ", String.valueOf(userid));
}
});
}
}
Adapter class :
public class UserAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
public UserAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.userprofiles, null);
TextView username = (TextView) view.findViewById(R.id.userName);
ImageView userImage = (ImageView) view.findViewById(R.id.userImage);
HashMap<String, String> usersList = new HashMap<>();
usersList = data.get(position);
username.setText(usersList.get(OtherUsers.firstName));
byte [] encodeByte=Base64.decode(usersList.get(OtherUsers.userImage).getBytes(), Base64.DEFAULT);
Bitmap bitmap=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
userImage.setImageBitmap(bitmap);
return view;
}
}
No image is seen, cant see in Log.d the clicked id. Unfortunately no errors to diagnose whats wrong.
Update
userprofiles.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:orientation="vertical"
android:weightSum="1">
<ImageView
android:id="#+id/userImage"
android:layout_width="140dp"
android:layout_height="200dp"
android:scaleType="fitXY"
android:padding="5dp"
android:src="#drawable/profile"
/>
<TextView
android:id="#+id/userName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:gravity="center"
android:layout_gravity="center_horizontal|top"
android:maxLines="1"
android:ellipsize="end"
android:scrollHorizontally="true"
android:layout_marginTop="10dp"
android:layout_weight="1.10" />
</LinearLayout>
</RelativeLayout>
PhotoSaving code :
public class AddPhotoForUser extends Activity {
private static final int CAMERA_PIC_REQUEST = 22;
Button BtnSelectImage;
private ImageView ImgPhoto;
private static volatile Bitmap photo;
private static volatile ByteArrayOutputStream stream = new ByteArrayOutputStream();
final PersonServiceImpl personService = new PersonServiceImpl();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.upload_user_photo);
Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
uploadImageButton.setVisibility(View.INVISIBLE);
ImgPhoto = (ImageView) findViewById(R.id.userPhotoImageView);
BtnSelectImage = (Button) findViewById(R.id.userPhotoButtonSelect);
BtnSelectImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Couldn't load photo", Toast.LENGTH_LONG).show();
}
}
});
uploadImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!(v == null)) {
uploadImage();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent intent = new Intent(AddPhotoForUser.this, RestaurantList.class);
startActivity(intent);
finish();
}
}
});
}
#Override
public void onBackPressed() {
Intent intent = new Intent(AddPhotoForUser.this, Login.class);
startActivity(intent);
finish();
}
#Override
public void onActivityResult(final int requestCode, int resultCode, Intent data) {
try {
switch (requestCode) {
case CAMERA_PIC_REQUEST:
if (resultCode == RESULT_OK) {
try {
photo = (Bitmap) data.getExtras().get("data");
if (!(photo == null)) {
ImgPhoto.setImageBitmap(photo);
Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
uploadImageButton.setVisibility(View.VISIBLE);
}
} catch (Exception e) {
Toast.makeText(this, "Couldn't load photo", Toast.LENGTH_LONG).show();
}
}
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void uploadImage() {
if (!(photo == null)) {
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
personService.addUserProfilePhoto(Base64.encodeToString(byteArray, Base64.DEFAULT));
}
}
}
Now , this calls the method to save it in DB. Currently, because byte-array was harassing so much, I have changed it to String.
Here is how it looks in DB now :
ImlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFLQUFBQUI0Q0FJQUFBRDZ3RzQ0QUFBQUEzTkNTVlFJ
Q0FqYjRVL2dBQUFDZlVsRVFWUjRcbm5PM2RNWkxTWUJpQTRlOTNNcE40QmtvT29CVjBNTE9sVmg1
Q08rZ292SUUxV0ducEFUekMxcFI2QnpydHRXSUx0akpqTmo4a0pMejdcblB1V1NmUG1YZDhqT0xB
bWt6V1lURWJ2ZExuS3NWcXVzN1owLzFQd1hXWE4xY3d3TVoyQzRvbytoNzc1KytmY25WWmszb2pi
aGlTTldcblpVVGMvZm1iZDVSbndGY3dYSnBPcHhFeG44K3pkdHZ2OXcyUGZ2djk2NkpGbmV2em03
Y3R0MnhlZjEyM3o4ODE1eGVId3lFaUpwTkpcbjFnRk9lLzFYN2dtNUkrMS9peWZXZjhIa3NjMzNG
QTFuWURnRHd4a1l6c0J3Qm9Zek1KeUI0UXdNWjJBNEE4TVpHTTdBY0FhR1M0dkZcbklpSlNTbG03
SFkvSGhrYy8vZnh4MGFMTzlmSFY2NVpiTnErL3J0dm41NXJ6aTlOYnpSMWZ0amxRNFBadmc0L25z
dGErNTN1S2hqTXdcbm5JSGhEQXhuWURnRHd4a1l6c0J3Qm9Zek1KeUI0UXdNWjJBNEE4UDFjL3Zv
UUx4OXRDNlZaUmtSNi9VNjZ3RGI3YmJoMGZ1WFZkYTBcbnJueC8vNkhsbHMzcnIrdjIrYm5tL0NM
M1dvS1Q4L1lhajc3WFA1NzUvZzJHTXpDY2dlRjYrWnlzK3VkVmplY2l0T2ZHVnpDY2dlRU1cbkRH
ZGdPQVBER1JqT3dIQUdoak13bklIaGl0TS8rVzczL2xmbk4vTVZER2RnT0FQREdSak93SEFHaGpN
d25JSGhEQXhuWURnRHd4a1lcbnpzQndCb1o3dkxNaDkvT05jemwvcVBtOWZFRjBuZk9IbW4rbE8v
eWRQOVI4L3diREdSak93SEFHaGpNd25JSGhEQXhuWURnRHd4a1lcbnpzQndCb1l6TUp5QjRkSnl1
WXd4ZmFHeDg3dWRYOHhtczdqbEc1eWQzOHhUTkp5QjRRd01aMkE0QThNWkdNN0FjQWFHTXpDY2dl
RU1cbkRHZGdPQVBER1JqTzIwZmg4MU5WVlRHbTl5K2QzKzE4VDlGd0JvWXpNSnlCNFF3TVoyQTRB
OE1aR003QWNBYUdNekNjZ2VFTURHZGdcbk9BUERQUUE2L2ZhYjNyY3BjQUFBQUFCSlJVNUVya0pn
Z2c9PVxuIg==
Below methods are used to add photo and retrieve users from server :
#Override
public void addUserProfilePhoto(final String profilePhoto) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
// headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(profilePhoto, headers);
ResponseEntity<Boolean> out = restTemplate.exchange(addPhotoUrl, HttpMethod.POST, entity, Boolean.class);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public List<RestPerson> getOtherUsers() {
final RestTemplate restTemplate = StaticRestTemplate.getRest();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
requestHeaders.setAccept(Collections.singletonList(new MediaType("application", "json")));
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
responseEntity = restTemplate.exchange(getOtherusers, HttpMethod.GET, requestEntity, RestPerson[].class);
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
RestPerson[] restPersonsArray = responseEntity.getBody();
List<RestPerson> restPersonArrayList = new ArrayList<>();
Collections.addAll(restPersonArrayList, restPersonsArray);
return restPersonArrayList;
}
Ensure you have set
android:descendantFocusability="blocksDescendants" in your R.layout.userprofiles.
This prevent that other focusable or clickable item in your row definition intercept row click.
Secondly, try to set a background color to your imageview and very that this "colored" view is really visible or not.
Edit
Finaly your getItem on adapter class is wrong: you have to return data.get(position)
First thing, You set the image bitmap twice here:
userImage.setImageBitmap(bitmap);
userImage.setImageBitmap(null);
make sure to remove the last line, which sets the image bitmap to null.
About the onItemClickListener, make sure you cleared the logcat filtering text, selected Log level to debug, and select the option "No filters" instead of "Show only selected Application" just to be sure you are not filtering out Your logs.
Check if the count of restPersonList is equal to 0,and add a log in method getView。
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm wanting to put a search bar to act as a filter for the data displayed in the listview.I could not find any examples that do something like that.
If someone can show me how I can do this or demonstrate an example I am very grateful.
public class ListFragment extends Fragment {
//the GridView
GridView lv;
Bitmap bitmap;
//The list that contains the menuitems (sort)
ArrayList<HashMap<String, String>> menuItems;
ProgressDialog pDialog;
View btnLoadMore;
Spinner spinner;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
//The list that contains the wallappers
ArrayList<Wallpaper> productsList;
//The adapter of the WallPaperList
WallPaperAdapter adapter;
private final String baseurl = AppConstant.BASE_URL;
String list_url;
// url to get all products list
private String url_all_products = baseurl + "get_all_products.php";
private String get_tag_products = baseurl + "get_tag_products.php";
// Flag for current page
int current_page = 0;
int max_pages;
// Prevent loading more items to the GridView twice
boolean isLoading;
//
String sort_order;
String tag;
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCTS = "products";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";
private static final String TAG_PAGE = "page";
private static final String TAG_ORDER = "order";
private static final String TAG_TAG = "tag";
private static final String TAG_THUMBURL = "url";
private static final String TAG_TOTAL_PAGE = "total_page";
// products JSONArray
JSONArray products = null;
// listener for sort order
private OnItemSelectedListener itemSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
Log.v("Selected: ", Integer.toString(position));
if (position == 0){
sort_order = "latest";
} else if (position == 1){
sort_order = "popular";
} else if (position == 2){
sort_order = "oldest";
} else if (position == 3){
sort_order = "alphabet";
}
//"resetting the GridView"
productsList.clear();
if (adapter != null){
adapter.clear();
}
current_page = 0;
isLoading = false;
//TODO footerview is not visible
ConnectivityManager cm =
(ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
new InitialLoadGridView().execute();
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.no_internet), Toast.LENGTH_LONG).show();
Intent intent = new Intent(getActivity(), ImageGridActivity.class);
startActivity(intent);
}
//}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_listfragment, null);
lv = (GridView)view.findViewById(R.id.listView);
setRetainInstance(true);
setHasOptionsMenu(true);
return view;
}
*#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.pesquisa, menu);
super.onCreateOptionsMenu(menu,inflater);
//Pega o Componente.
SearchView mSearchView = (SearchView) menu.findItem(R.id.search)
.getActionView();
//Define um texto de ajuda:
mSearchView.setQueryHint("teste");
// exemplos de utilização:
return;
}*
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ActionBar actions = getActivity().getActionBar();
actions.setDisplayShowTitleEnabled(false);
// Adapter
SpinnerAdapter spinadapter =
ArrayAdapter.createFromResource(getActivity(), R.array.actions,
//android.R.layout.simple_spinner_dropdown_item);
R.layout.actionbar_spinner_item);
Spinner navigationSpinner = new Spinner(getActivity());
navigationSpinner.setAdapter(spinadapter);
// Here you set navigation listener
navigationSpinner.setOnItemSelectedListener(itemSelectedListener);
actions.setCustomView(navigationSpinner);
if (getActivity().getActionBar().getCustomView().getVisibility() == View.INVISIBLE){
getActivity().getActionBar().getCustomView().setVisibility(View.VISIBLE);
}
actions.setDisplayShowCustomEnabled(true);
//ListFragment is created, so let's clear the imageloader cache
ImageLoader.getInstance().clearMemoryCache();
// Arraylist for GridView
productsList = new ArrayList<Wallpaper>();
//initialize the footer so it can be used
btnLoadMore = View.inflate(getActivity(), R.layout.footerview, null);
if ((getResources().getString(R.string.ad_visibility).equals("0"))){
// Look up the AdView as a resource and load a request.
AdView adView = (AdView) getActivity().findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
}
//TODO Implement and replace old
lv.setOnScrollListener(new OnScrollListener(){
int currentVisibleItemCount;
int currentScrollState;
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.currentVisibleItemCount = visibleItemCount;
}
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
private void isScrollCompleted() {
if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
/*** In this way I detect if there's been a scroll which has completed ***/
/*** do the work for load more date! ***/
if(!isLoading){
isLoading = true;
if (max_pages != current_page){
new loadMoreGridView().execute();
} else {
Log.v("INFO", "Not loading more items because everything is already showing");
}
}
}
}
});
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//String pid = ((TextView) view.findViewById(R.id.pid)).getText().toString();
String pid = productsList.get(position).getPid();
boolean singlepane = MainActivity.getPane();
if(singlepane== true){
/*
* The second fragment not yet loaded.
* Load DetailFragment by FragmentTransaction, and pass
* data from current fragment to second fragment via bundle.
*/
DetailFragment detailFragment = new DetailFragment();
Fragment myListFragment = getFragmentManager().findFragmentByTag("ListFragment");
Bundle bundle = new Bundle();
bundle.putString("TAG_PID",pid);
detailFragment.setArguments(bundle);
FragmentTransaction fragmentTransaction =
getActivity().getFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(
R.anim.fadein, R.anim.fadeout, R.anim.fadein, R.anim.fadeout);
//This could use some improvement, but it works, hide current fragment, show new one
fragmentTransaction.hide(myListFragment);
fragmentTransaction.add(R.id.phone_container, detailFragment);
//fragmentTransaction.show(myDetailFragment);
/*
* Add this transaction to the back stack.
* This means that the transaction will be remembered after it is
* committed, and will reverse its operation when later popped off
* the stack.
*/
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
});
}
/**
* Async Task that send a request to url
* Gets new list view data
* Appends to list view
* */
private class loadMoreGridView extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
protected Void doInBackground(Void... unused) {
// increment current page
current_page += +1;
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(TAG_PAGE, Integer.toString(current_page)));
params.add(new BasicNameValuePair(TAG_ORDER, (sort_order)));
if (tag != null){
params.add(new BasicNameValuePair(TAG_TAG, (tag)));
} else {
list_url = url_all_products;
}
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(list_url, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String thumburl = c.getString(TAG_THUMBURL);
// adding items to arraylist
productsList.add(new Wallpaper(name, thumburl, id));
}
} else {
// no products found
}
} catch (JSONException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
public void run() {
//OUTDATED - Listview seems to automatically keep up with the position
//get GridView current position - used to maintain scroll position
//int currentPosition = lv.getFirstVisiblePosition();
// Appending new data to menuItems ArrayList
adapter.notifyDataSetChanged();
//OUTDATED - Setting new scroll position
//lv.setSelectionFromTop(currentPosition + 1, 0);
if (current_page == max_pages){
adapter.RemoveFooterView();
} else {
adapter.setFooterView(btnLoadMore);
}
}
});
return (null);
}
protected void onPostExecute(Void unused) {
// closing progress dialog
isLoading = false;
}
}
/**
* Async Task that send a request to url
* Gets new list view data
* Appends to list view
* */
private class InitialLoadGridView extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(
getActivity());
pDialog.setMessage(getResources().getString(R.string.wait));
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
}
protected Void doInBackground(Void... unused) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(TAG_ORDER, (sort_order)));
try { tag = getActivity().getIntent().getExtras().getString("TAG"); } catch (Exception e){}
if (tag != null){
list_url = get_tag_products;
params.add(new BasicNameValuePair(TAG_TAG, (tag)));
} else {
list_url = url_all_products;
}
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(list_url, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
max_pages = json.getInt(TAG_TOTAL_PAGE);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String thumburl = c.getString(TAG_THUMBURL);
// creating new HashMap
//HashMap<String, String> map = new HashMap<String, String>();
// adding items to arraylist
productsList.add(new Wallpaper(name, thumburl, id));
}
} else {
// no products found
}
} catch (JSONException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
public void run() {
// Getting adapter
adapter = new WallPaperAdapter(
getActivity(), productsList);
lv.setAdapter(adapter);
current_page = 0;
if (current_page == max_pages){
adapter.RemoveFooterView();
} else {
adapter.setFooterView(btnLoadMore);
}
}
});
return (null);
}
protected void onPostExecute(Void unused) {
// closing progress dialog
pDialog.dismiss();
lv.post(new Runnable() {
public void run() {
//check if last item is visible, in that case, load some more items
if (lv.getLastVisiblePosition() == lv.getAdapter().getCount() -1 &&
lv.getChildAt(lv.getChildCount() - 1).getBottom() <= lv.getHeight() )
{
if(!isLoading){
isLoading = true;
if (max_pages != current_page){
new loadMoreGridView().execute();
Log.v("INFO", "Last Item Visible and more available so loading more");
} else {
Log.v("INFO", "Already showing max pages");
}
}
} else {
Log.v("INFO", "Last Item Not Visible, not loading more");
}
}
});
}
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
Fragment myListFragment = getFragmentManager().findFragmentByTag("ListFragment");
if (myListFragment != null && myListFragment.isVisible()) {
//VISIBLE! =)
Log.d("STATE", "Just became visible!");
getActivity().getActionBar().getCustomView().setVisibility(View.VISIBLE);
getActivity().getActionBar().setDisplayShowTitleEnabled(false);
}
}
public static int convertDpToPixels(float dp, Context context){
Resources resources = context.getResources();
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
resources.getDisplayMetrics()
);
}
public interface MyFragInterface {
public void needsHide();
}
public static boolean isInVisible(GridView scrollView, View view, Rect region, boolean relative)
{
int top = scrollView.getScrollY() + region.top;
int bottom = scrollView.getScrollY() + region.bottom;
if(!relative)
{
// If given region is not relative to scrollView
// i.e 0,0 does not point to first child left and top
top -= scrollView.getTop();
bottom -= scrollView.getTop();
}
Rect rect = new Rect(region);
rect.top = top;
rect.bottom = bottom;
Rect childRegion = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
return Rect.intersects(childRegion, region);
}
}
Using AutoCompleteTextView for search bar is the simplest way for me, following is a sample code,hope that will help.
Layout Xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity$PlaceholderFragment" >
<AutoCompleteTextView
android:id="#+id/search_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search"
android:inputType="text"
android:lines="1"
android:textColor="#color/white"
android:textSize="20sp"
android:textStyle="bold" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/search_text"
android:background="#color/white"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<ListView
android:id="#+id/countries_list"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</ListView>
</RelativeLayout>
Fragment:
public static class PlaceholderFragment extends Fragment implements AdapterView.OnItemClickListener {
AutoCompleteTextView searchTextview;
ListView capitalList;
ArrayAdapter searchTextviewAdapter;
private View rootView;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main, container, false);
getActivity().setTitle(" Letsgomo");
searchTextview= (AutoCompleteTextView) rootView.findViewById(R.id.search_text);
capitalList= (ListView) rootView.findViewById(R.id.countries_list);
searchTextviewAdapter=new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1,Constants.capitals);
searchTextview.setAdapter(searchTextviewAdapter);
ArrayAdapter capitalAdapter= (ArrayAdapter) searchTextview.getAdapter();
capitalList.setAdapter(capitalAdapter);
capitalList.setOnItemClickListener(this);
return rootView;
}
}
This question already has an answer here:
JSON String is incorrectly mapped to textviews
(1 answer)
Closed 9 years ago.
I have a JSON request which returns a response from youtube containing the comments for a particular video. I currently have 3 textviews: one for the name/uploader, one for the content, and one for the date published - which are then populated with the data from my JSON response.
My problem is - only the first comment, date published and uploader appear.
I belive I'll need to replace my textviews with a list view and parse the 3 fields to it - I simply do not know how.
JAVA
public class Player extends YouTubeBaseActivity implements
YouTubePlayer.OnInitializedListener {
public static final String API_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
String title = getIntent().getStringExtra("title");
String uploader = getIntent().getStringExtra("uploader");
String viewCount = getIntent().getStringExtra("viewCount");
TextView titleTv = (TextView) findViewById(R.id.titleTv);
TextView uploaderTv = (TextView) findViewById(R.id.uploaderTv);
TextView viewCountTv = (TextView) findViewById(R.id.viewCountTv);
titleTv.setText(title);
uploaderTv.setText("by" + uploader + " |");
viewCountTv.setText(viewCount + " views");
YouTubePlayerView youTubePlayerView = (YouTubePlayerView) findViewById(R.id.youtubeplayerview);
youTubePlayerView.initialize(API_KEY, this);
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
return false;
}
});
GetYouTubeUserCommentsTask task = new GetYouTubeUserCommentsTask(handler , viewCount);
task.execute();
}
#Override
public void onInitializationFailure(Provider provider,
YouTubeInitializationResult result) {
Toast.makeText(getApplicationContext(), "onInitializationFailure()",
Toast.LENGTH_LONG).show();
}
#Override
public void onInitializationSuccess(Provider provider,
YouTubePlayer player, boolean wasRestored) {
if (!wasRestored) {
String video_id = getIntent().getStringExtra("id");
player.loadVideo(video_id);
}
}
public final class GetYouTubeUserCommentsTask extends
AsyncTask<Void, Void, Void> {
public static final String LIBRARY = "CommentsLibrary";
private final Handler replyTo;
private final String username;
String video_id = getIntent().getStringExtra("id");
public GetYouTubeUserCommentsTask(Handler replyTo, String username) {
this.replyTo = replyTo;
this.username = username;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
HttpClient client = new DefaultHttpClient();
HttpUriRequest request = new HttpGet(
"http://gdata.youtube.com/feeds/api/videos/"
+ video_id
+ "/comments?v=2&alt=json&start-index=1&max-results=50&prettyprint=true");
HttpResponse response = client.execute(request);
String jsonString = StreamUtils.convertToString(response
.getEntity().getContent());
JSONObject json = new JSONObject(jsonString);
JSONArray jsonArray = json.getJSONObject("feed").getJSONArray(
"entry");
List<Comments> comments = new ArrayList<Comments>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject entry = jsonArray.getJSONObject(i);
JSONArray authorArray = entry.getJSONArray("author");
JSONObject publishedObject = entry.getJSONObject("published");
String published = publishedObject.getString("$t");
JSONObject contentObject = entry.getJSONObject("content");
String content = contentObject.getString("$t");
JSONObject authorObject = authorArray.getJSONObject(0);
JSONObject nameObject = authorObject.getJSONObject("name");
String name = nameObject.getString("$t");
comments.add(new Comments(name, content, published));
CommentsLibrary lib = new CommentsLibrary(published, content, name);
Bundle data = new Bundle();
data.putSerializable(LIBRARY, lib);
Message msg = Message.obtain();
msg.setData(data);
replyTo.sendMessage(msg);
}
} catch (ClientProtocolException e) {
Log.e("Feck", e);
} catch (IOException e) {
Log.e("Feck", e);
} catch (JSONException e) {
Log.e("Feck", e);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
ListView comments = (ListView) findViewById(R.id.comments);
comments.setFilterText(com.idg.omv.domain.CommentsLibrary.getName());
}
}
}
CommentsLibrary
public class CommentsLibrary implements Serializable{
// The username of the owner of the comment
private static String name;
// The comment
private static String content;
// The date the comment was published
private static String published;
public CommentsLibrary(String name, String content, String published) {
this.name = name;
this.content = content;
this.published = published;
}
/**
* #return the user name
*/
public static String getName() {
return name;
}
/**
* #return the videos
*/
public static String getContent() {
return content;
}
/**
* #return the videos
*/
public static String getPublished() {
return published;
}
}
XML
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left"
android:text="" />
<TextView
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/name"
android:layout_weight="1"
android:gravity="left"
android:text="" />
<TextView
android:id="#+id/published"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/content"
android:layout_weight="1"
android:gravity="left"
android:text="" />
Continuing my answer from your previous question # JSON String is incorrectly mapped to textviews
First you need a listview in your layout xml
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
Declare list as a instance variable
ArrayList<CommentsLibrary> list = new ArrayList<CommentsLibrary>();
Then
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String name = jsonObject.optString("name","defaultValue");
String content = jsonObject.optString("content","defaultValue");
String published = jsonObject.optString("published","defaultValue");
list.add(new CommentsLibrary(name, content, published));
}
Then initialize listview
ListView lv =(ListView)findViewById(R.id.list);
CustomAdapter cus = new CustomAdapter(ActivityName.this,list);
lv.setAdapter(cus);
Define a custom layout with 3 textviews. (list_item.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="18dp"
android:layout_marginTop="31dp"
android:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView1"
android:layout_alignBottom="#+id/textView1"
android:layout_centerHorizontal="true"
android:text="TextView" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView2"
android:layout_alignBottom="#+id/textView2"
android:layout_alignParentRight="true"
android:layout_marginRight="24dp"
android:text="TextView" />
</RelativeLayout>
Then define a custom adapter by extending a base adapter. Override getView inflate the custom layout and set text views there.
public class CustomAdapter extends BaseAdapter
{
LayoutInfalter mInflater;
ArrayList<CommentsLibrary> list;
public CustomAdapter(Context context,ArrayList<CommentsLibrary> list)
{
mInflater = LayoutInfalter.from(context);
this.list = list;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if(convertView==null)
{
convertView =minflater.inflate(R.layout.list_item, parent,false);
holder = new ViewHolder();
holder.tv1 = (TextView) convertView.findViewById(R.id.textView1);
holder.tv2 = (TextView) convertView.findViewById(R.id.textView2);
holder.tv3 = (TextView) convertView.findViewById(R.id.textView3);
convertView.setTag(holder);
}
else
{
holder= (ViewHolder) convertView.getTag();
}
holder.tv1.setText(list.get(position).getName());
holder.tv2.setText(list.get(position).getContent());
holder.tv3.setText(list.get(position).getPublished());
return convertView;
}
static class ViewHolder
{
TextView tv1,tv2,tv3
}
}
You need to add a list view in your layout and populate it using an ArrayAdapter. Here's a tutorial that shows you how - http://www.vogella.com/articles/AndroidListView/article.html#arrayAdapter