I am trying to do a fragment where there is a listview inside and I am trying to populate the listview using JSON. I only have one error and i dont know where to put the single error i have.
The error is pointing at the getJSON(); just below the return rootview saying invalid method declaration
Here is my code where it extends a fragment and inside is a listview
public class News extends Fragment {
private ListView lv;
private String JSON_STRING;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(news, container, false);
lv = (ListView) rootView.findViewById(R.id.listView3);
return rootView;
}
getJSON();
private void showResult(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY1);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String NID = jo.getString(Config.TAG_NID);
String title = jo.getString(Config.TAG_title);
String content = jo.getString(Config.TAG_content);
String n_date = jo.getString(Config.TAG_n_date);
HashMap<String,String> match = new HashMap<>();
match.put(Config.TAG_NID, NID);
match.put(Config.TAG_title,title);
match.put(Config.TAG_content,content);
match.put(Config.TAG_n_date,n_date);
list.add(match);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(
getActivity(), list, R.layout.newsadapterlayout,
new String[]{Config.TAG_title,Config.TAG_content, Config.TAG_n_date, Config.TAG_NID},
new int[]{ R.id.title, R.id.content, R.id.n_date});
lv.setAdapter(adapter);
}
private void getJSON(){
class GetJSON extends AsyncTask<Void,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSON_STRING = s;
showResult();
}
#Override
protected String doInBackground(Void... params) {
RequestHandler rh = new RequestHandler();
String s = rh.sendGetRequest(Config.URL_NEWS);
return s;
}
}
GetJSON gj = new GetJSON();
gj.execute();
}
Any help would be very much appreciated. Thanks guys
You can't declare a class inside of a method.
Separate private void getJSON() from the class GetJSON, simply move the code outside of the method, you can still do; GetJSON gj = new GetJSON();
Related
how do i populate my listview with JSON inside a fragment. The app runs with no error, but the listview is empty. I am not getting any data inside my fragment. But when i make it as an activity and not as a fragment the listview is populated with JSON data.
Here is my fragment code with listview and json parsing
public class News extends Fragment {
private ListView lv;
private String JSON_STRING;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(news, container, false);
lv = (ListView) rootView.findViewById(R.id.listView3);
getJSON();
return rootView;
}
private void showResult(){
JSONObject jsonObject;
ArrayList<HashMap<String,String>> list = new ArrayList<>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY1);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String title = jo.getString(Config.TAG_title);
HashMap<String,String> match = new HashMap<>();
match.put(Config.TAG_title,title);
list.add(match);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(
getActivity(), list, R.layout.newsadapterlayout,
new String[]{Config.TAG_title,Config.TAG_content, Config.TAG_n_date, Config.TAG_NID},
new int[]{ R.id.title});
lv.setAdapter(adapter);
}
private void getJSON(){
class GetJSON extends AsyncTask<Void,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSON_STRING = s;
showResult();
}
#Override
protected String doInBackground(Void... params) {
RequestHandler rh = new RequestHandler();
String s = rh.sendGetRequest(Config.URL_NEWS);
return s;
}
}
GetJSON gj = new GetJSON();
gj.execute();
}
Solved it, I forgot to add permissions in manifest lol
Here is my logcat
/* setup these below variables */
private int currentScrollState, currentFirstVisibleItem, currentVisibleItemCount, currentTotalItemCount;
if (lv.size() > 0) {
ListAdapter adapter = new SimpleAdapter(
getActivity(), list, R.layout.newsadapterlayout,
new String[]{Config.TAG_title,Config.TAG_content, Config.TAG_n_date, Config.TAG_NID},
new int[]{ R.id.title});
adapter.notifyDataSetChanged();
list.setAdapter(adapter);
lv.setSelectionFromTop(currentFirstVisibleItem, 0); /* you missed here*/
}
Implement other ListView callbacks something like below:
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.currentTotalItemCount = totalItemCount;
}
private void isScrollCompleted() {
if (currentFirstVisibleItem + currentVisibleItemCount >= currentTotalItemCount) {
if (this.currentVisibleItemCount > 0 && this.currentScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
}
}
}
I am trying to do a fragment where there is a listview inside and I am trying to populate the listview using JSON. I only have one error and i dont know where to put the single error i have. The error says unreachable statement, when i put the getJSON() below the } it says invalid method declaration
Here is my code with the listview inside a fragment. There error is pointing at the getJSON(); below the rootview. Thanks
public class News extends Fragment {
private ListView lv;
private String JSON_STRING;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(news, container, false);
lv = (ListView) rootView.findViewById(R.id.listView3);
return rootView;
getJSON();
}
private void showResult(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY1);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String NID = jo.getString(Config.TAG_NID);
String title = jo.getString(Config.TAG_title);
String content = jo.getString(Config.TAG_content);
String n_date = jo.getString(Config.TAG_n_date);
HashMap<String,String> match = new HashMap<>();
match.put(Config.TAG_NID, NID);
match.put(Config.TAG_title,title);
match.put(Config.TAG_content,content);
match.put(Config.TAG_n_date,n_date);
list.add(match);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(
getActivity(), list, R.layout.newsadapterlayout,
new String[]{Config.TAG_title,Config.TAG_content, Config.TAG_n_date, Config.TAG_NID},
new int[]{ R.id.title, R.id.content, R.id.n_date});
lv.setAdapter(adapter);
}
private void getJSON(){
class GetJSON extends AsyncTask<Void,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSON_STRING = s;
showResult();
}
#Override
protected String doInBackground(Void... params) {
RequestHandler rh = new RequestHandler();
String s = rh.sendGetRequest(Config.URL_NEWS);
return s;
}
}
GetJSON gj = new GetJSON();
gj.execute();
}
}
Your getJSON() call is after your return statement, so it is not possible for it to ever be executed. That is what the "unreachable statement" error means.
You could move your getJSON() call to the line before your return statement and it should solve that problem. Without running it it's hard to know if there will then be other problems, but at least that one should be solved.
Protip: put errors you don't understand into your favorite search engine. In this case a search for java unreachable statement will yield plenty of results explaining that your problem is that you have a statement after a return:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(news, container, false);
lv = (ListView) rootView.findViewById(R.id.listView3);
return rootView; // <- Returning from the function here
getJSON(); // <- How is this supposed to get executed if you already returned?
}
Call getJSON before returning from the method.
I have a listview that after refreshing it and getting new data. It goes to the top of the listview and not where I last scrolled it to.
I have set a timer that after 2 seconds, it gets new data and puts it into the listview.
Any help would be greatly appreciated. Thanks in advance :D
Here is the Mainactivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
listView.setOnItemClickListener(this);
getJSON();
handler.postDelayed(runnable, 3500);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
getJSON();
handler.postDelayed(this, 2000);
}
};
private void showEmployee(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String id = jo.getString(Config.TAG_ID);
String name = jo.getString(Config.TAG_NAME);
HashMap<String,String> employees = new HashMap<>();
employees.put(Config.TAG_ID,id);
employees.put(Config.TAG_NAME,name);
list.add(employees);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, list, R.layout.list_item,
new String[]{Config.TAG_ID,Config.TAG_NAME},
new int[]{R.id.id, R.id.name});
listView.setAdapter(adapter);
}
private void getJSON(){
class GetJSON extends AsyncTask<Void,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSON_STRING = s;
showEmployee();
}
#Override
protected String doInBackground(Void... params) {
RequestHandler rh = new RequestHandler();
String s = rh.sendGetRequest(Config.URL_GET_ALL);
return s;
}
}
GetJSON gj = new GetJSON();
gj.execute();
}
in onCreate() initialize your adapter with empty list and bind with listView.
make your adapter and list global in class.
now whenever you add data to adapter just call adapter.notifyDataSetChanged()
this is how it also works in fragment.
The ListView is scrolled to the top because the Adapter is set again. Instead of setting the Adapter each time new data is recieved, you can simply add the new data to the already existing List/dataset and call notifyDatasetChanged() on the ListView's Adapter. The ListView's position wont change.
To restore the scroll position use this.
Parcelable state;
#Override
public void onPause() {
// Save ListView state # onPause
Log.d(TAG, "saving listview state # onPause");
state = listView.onSaveInstanceState();
super.onPause();
}
...
#Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set new items
listView.setAdapter(adapter);
...
// Restore previous state (including selected item index and scroll position)
if(state != null) {
Log.d(TAG, "trying to restore listview state..");
listView.onRestoreInstanceState(state);
}
}
Try this in your listview's onScrollListner get the position of your last visible item and when you load more data, set listview's setSelection
int ScrollPos=0;
listview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
int threshold = 1;
int count = listview.getCount();
if (listViewList1.size() >= YOUR LOAD ELEMENTS SIZE(Everytime))
if (scrollState == SCROLL_STATE_IDLE) {
if (listview.getLastVisiblePosition() >= count
- threshold) {
scrollPos = listViewList.size();
// Execute LoadMoreDataTask AsyncTask
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
and while again fetching more data just call Listview.setSelection(scrollPos)
and for the first time just manage to set you scrollpos back to 0
hope this will help you
You must declare the adapter and the list as instance variables instead of declaring them locally. Whenever there is any change in data, you must do the respection update operation on the list and then call adapter's notifyDataSetChanged() method to update the listview.
Change your code to this :
ArrayList<HashMap<String,String>> list;
ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
list = new ArrayList<HashMap<String, String>>();//changed
adapter = new SimpleAdapter(
MainActivity.this, list, R.layout.list_item,
new String[]{Config.TAG_ID,Config.TAG_NAME},
new int[]{R.id.id, R.id.name});//changed
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
getJSON();
handler.postDelayed(runnable, 3500);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
getJSON();
handler.postDelayed(this, 2000);
}
};
private void showEmployee(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String id = jo.getString(Config.TAG_ID);
String name = jo.getString(Config.TAG_NAME);
HashMap<String,String> employees = new HashMap<>();
employees.put(Config.TAG_ID,id);
employees.put(Config.TAG_NAME,name);
list.add(employees);
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();//changed
}
private void getJSON(){
class GetJSON extends AsyncTask<Void,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSON_STRING = s;
showEmployee();
}
#Override
protected String doInBackground(Void... params) {
RequestHandler rh = new RequestHandler();
String s = rh.sendGetRequest(Config.URL_GET_ALL);
return s;
}
}
GetJSON gj = new GetJSON();
gj.execute();
}
I want to send a list of bitmap i retreived from mysql database using asyncTask to the fragment Fragment_ListView.class, in this fragment class i want to set the adapter of the listView with the bitmap token from asyncTask but i don't know how to do that.
Async Task
#Override
protected void onPostExecute(ArrayList<Bitmap> bitmapArrayList) {
super.onPostExecute(bitmapArrayList);
loading.dismiss();
// now after getting images from server , i want to send this bitmapArrayList
// to Fragment_ListView where i set the adapter of the
}
#Override
protected ArrayList<Bitmap> doInBackground(String... params) {
imageList = new ArrayList();
String add1 = "http://192.168.1.11/save/load_image_from_db.php?id=1";
String add2 = "http://192.168.1.11/save/load_image_from_db.php?id=2";
String add3 = "http://192.168.1.11/save/load_image_from_db.php?id=3";
URL url;
Bitmap image = null;
String[] adds = {add1, add2, add3};
for (int i = 0; i < adds.length; i++) {
try {
url = new URL(adds[i]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
image = BitmapFactory.decodeStream(connection.getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
imageList.add(image);
image = null;
}
return imageList;
OnCreate of MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listfrg = new Fragment_ListView();
getFragmentManager().beginTransaction().add(R.id.frml, listfrg).commit();
}
Fragment_ListView :
public class Fragment_ListView extends Fragment {
ListView mListView;
static ArrayList<Bitmap> bitmaps;
static MySimpleArrayAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frglist, container, false);
mListView = (ListView) view.findViewById(R.id.listView);
bitmaps = new ArrayList<>();
adapter = new MySimpleArrayAdapter(getActivity(), bitmaps);
mListView.setAdapter(adapter);
return view;
}
Something like this,
Create a new interface file
public interface BitMapArrayCallBack {
abstract void bitmapArray(ArrayList<Bitmap> bitmaps);
}
Then in AsyncTask ... i don't know your class name so i will assume the class ServerRequest
public class ServerRequest {
Context context;
public ServerRequest(Context context) {
this.context = context;
}
public void doAsyncTask(BitMapArrayCallBack bitmapCallback) {
new MyAsyncTask(bitmapCallback).execute();
}
public class MyAsyncTask extends AsyncTask<Void, Void, Void> {
private BitMapArrayCallBack bitmapCallback;
public MyAsyncTask(BitMapArrayCallBack bitmapCallback) {
this.bitmapCallback = bitmapCallback;
}
//call do in background etc..
#Override
protected void onPostExecute(ArrayList<Bitmap> bitmapArrayList) {
super.onPostExecute(bitmapArrayList);
loading.dismiss();
bitmapCallback.bitmapArray(bitmapArrayList);
// This will hold and return your arraylist
}
}
}
Now you must call your asynctask in fragment listview
public class Fragment_ListView extends Fragment {
ListView mListView;
static MySimpleArrayAdapter adapter;
private ServerRequest serverRequest;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frglist, container, false);
mListView = (ListView) view.findViewById(R.id.listView);
serverRequest = new ServerRequest(getActivity);
serverRequest.doAsyncTask(new BitMapArrayCallBack {
#Override
void bitMapArray(ArrayList<Bitmap> bitmaps) {
// in here you have access to the bitmaps array
adapter = new MySimpleArrayAdapter(getActivity(), bitmaps);
mListView.setAdapter(adapter);
}
})
return view;
}
I've an activity which output json data from as a list. But now I want to implement it in a fragment.
In this fragment I want to view it as gridview. And both files works fine. but when I tried to implement AsyncTask I gets several redflags as unreachable code. Can someone help me with this please?
Edited: New
public class SalesFragment extends Fragment {
GridView gridView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View gv = inflater.inflate(R.layout.hot_sales, null);
gridView = (GridView) gv.findViewById(R.id.grid_view);
bindGridview();
return gv;
}
public void bindGridview() {
new MyAsyncTask(getActivity(),gridView).execute("");
}
class MyAsyncTask extends AsyncTask<String, String, String> {
GridView mGridView;
Activity mContext;
Response response;
public MyAsyncTask(Activity context,GridView gview) {
this.mGridView=gview;
this.mContext=context;
}
protected String doInBackground(String... params) {
File file = new File( Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/sample.txt");
if(file.exists()) {
try{
Reader inputStreamReader = new InputStreamReader(new FileInputStream(file));
Gson gson = new Gson();
this.response = gson.fromJson(inputStreamReader, Response.class);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (#SuppressWarnings("hiding") IOException e){
e.printStackTrace();
}
}else{
System.out.println("Error");
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
for(Sales sales : this.response.sales){
HashMap<String, String> hm = new HashMap<String,String>();
if (sales.getCategories1().contains("12")){
//hm.put("sale_title", "" + sales.getShort_title());
for(Shop shop : this.response.shops){
String image_file = new String( Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/images/" + shop.getImage());
if(shop.getId().equals(sales.getShop_id())){
hm.put("shop_image", image_file );
System.out.println(shop_image);
}
}
if(hm.size()>0){
gridView.setAdapter(new ImageAdapter(MainActivity.this,R.layout.grid_layout , imgArray, titleArray));
}
}
}
}
}
}
How to call images into gridview on above image? Please help.
There is easy step to crate asyntask within fragment
in your fragment place code on activityCreateview
new MyAsyncTask(getActivity(), mListView).execute("");
getActivity() is method to communicate with fragment and activity
in asynstak on post
context.mListView.setArrayAdapter(...........)
here is
public class SalesFragment extends Fragment {
GridView gridView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View gv = inflater.inflate(R.layout.hot_sales, null);
gridView = (GridView) gv.findViewById(R.id.grid_view);
bindGridView()
return gv;
//return super.onCreateView(inflater, container, savedInstanceState);
}
public void bindGridview()
{
new MyAsyncTask(getActivity(), gridView).execute("");
}
class MyAsyncTask extends AsyncTask<String, String, String>
{
GridView mGridView;
Activity mContex;
public MyAsyncTask(Activity contex,GridView gview)
{
this.mGridView=gview;
this.mContex=contex;
}
protected String doInBackground(String... params)
{
//fetch data
}
#Override
protected void onPostExecute(String result) {
{
for(Sales sales : this.response.sales){
HashMap<String, String> hm = new HashMap<String,String>();
if (sales.getCategories1().contains("12")){
//hm.put("sale_title", "" + sales.getShort_title());
for(Shop shop : this.response.shops){
String image_file = new String( Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/images/" + shop.getImage());
if(shop.getId().equals(sales.getShop_id())){
hm.put("shop_image", image_file );
System.out.println(shop_image);
}
}
}
}
if(hm.size()>0)
mcontext.mGridView.setAdapter(new ImageAdapter(mContext),hm);
}
before fetching data make it model like
public class ImageModel
{
String title;
String img;
}
ArrayList<ImageModel> arrayList=new ArrayList<ImageModel>();
fill array list with required data
then
mcontext.mGridView.setAdapter(new ImageAdapter(mContext),hm,arrayList);
//in image adapter
public class ImageAdapter extends ArrayAdapter<String> {
public ImageAdapter(Context context, HashMap<String, String> hm,ArrayList<ImageModel> images )
{
super(context, R.layout.activity_t);
}
//--code
}
use hash map in adapter and assign images with position
set data and fetch value from model