I am getting some news data from my CMS,and want to display them in a RecyclerView.The problem is that I am getting a null pointer exception in the line where I using the LinearLayoutManager. Here is the logcat output.
Caused by: java.lang.NullPointerException
at testing.theo.manchesterunitedapp.newsandfeatures.FeaturesFragment.onCreateView(FeaturesFragment.java:65)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5241)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2157)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
The Fragment where I am doing the webservice part is quite simple. I use to callback methods. The onCreateView where I am initialising the ArrayList and the RecyclerView,and secondly the onActivityCreate where I am running the webservice.
public class FeaturesFragment extends Fragment {
public static final String TAG = "ManuApp";
private static final String IMAGE_URL = "xxxxxxxxxxxx/xxxx/features_images/" ;
private List<FeaturesObject> listItemsList;
private RecyclerView mRecyclerView;
private FeaturesAdapter adapter;
public FeaturesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.features_row, container, false);
// Inflate the layout for this fragment
listItemsList = new ArrayList<>();
mRecyclerView = (RecyclerView)v.findViewById(R.id.features_recycler_view);
//mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).color(Color.BLACK).build());
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(linearLayoutManager);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
updateFeaturesList();
}
public void updateFeaturesList() {
//declare the adapter and attach it to the recyclerview
adapter = new FeaturesAdapter(getActivity(), listItemsList);
mRecyclerView.setAdapter(adapter);
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(getActivity());
// Request a string response from the provided URL.
JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, Config.URL_FEATURES, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
//hidePD();
// Parse json data.
// Declare the json objects that we need and then for loop through the children array.
// Do the json parse in a try catch block to catch the exceptions
try {
for (int i = 0; i < response.length(); i++) {
JSONObject post = response.getJSONObject(i);
FeaturesObject item = new FeaturesObject();
item.setTitle(post.getString("title"));
item.setImage(IMAGE_URL + post.getString("features_image"));
item.setArticle(post.getString("article"));
listItemsList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
// Update list by notifying the adapter of changes
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
//hidePD();
}
});
jsObjRequest.setRetryPolicy(new RetryPolicy() {
#Override
public int getCurrentTimeout() {
return 50000;
}
#Override
public int getCurrentRetryCount() {
return 50000;
}
#Override
public void retry(VolleyError error) throws VolleyError {
}
});
queue.add(jsObjRequest);
}
}
This part of the code causes the problem.
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(linearLayoutManager);
This is strange,as I am using the same techiques to obtain data in another fragment of my app.
Any ideas?
Thanks.
Your RecyclerView is null. Are you sure you're looking for the correct id in the correct layout file? My guess is either you are inflating the incorrect layout file, or you're looking for the incorrect view id for the RecyclerView.
Probably this is not the case but... As a general rule all initialization that need instance of the activity must be in onActivityCreated() (or the next methods in the Fragment lifecycle). Inside onCreateView() getActivity() is not guaranteed to return non-null value. In some scenarios it returns null.
Seems like the id that you are trying to find it's not on features_row that's why you get NullPointerException on that line :
mRecyclerView = (RecyclerView)v.findViewById(R.id.features_recycler_view);
If you keep getting error you could try this :
final FragmentActivity c = getActivity();
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(c);
mRecyclerView.setLayoutManager(linearLayoutManager );
Related
This question already has answers here:
I get the error "Unreachable statement" return in android
(3 answers)
Closed 3 years ago.
I have this code, which integrates a RecyclerView within a Fragment, but this line:
mRecyclerView = (RecyclerView) mRecyclerView.findViewById(R.id.list_data);
Gives me an error, it tells me that:
Unreachable statement
And I don't know why, any idea?
Here's the code I'm using:
public class KecamatanFragment extends Fragment {
private static final String data_url = "http://xxxxxxxxxx/daftar/get_kecamatan.php"; // kasih link prosesnya
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mManager;
ProgressDialog pd;
ArrayList<ModelData> mItems;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_kecamatan, container, false);
mRecyclerView = (RecyclerView) mRecyclerView.findViewById(R.id.list_data); <-- Unreachable statement
mItems = new ArrayList<>();
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
mAdapter = new AdapterProcess(KecamatanFragment.this, mItems);
mRecyclerView.setAdapter(mAdapter);
loadjson();
}
enter code here
//proses mengambil data
private void loadjson(){
pd.setMessage("Mengambil Data");
pd.setCancelable(false);
pd.show();
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.POST, data_url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
pd.cancel();
Log.d("volley", "response : " + response.toString());
for (int i=0; i < response.length(); i++){
try {
JSONObject data = response.getJSONObject(i);
ModelData md = new ModelData();
md.setKecamatan(data.getString("kecamatan")); // memanggil nama array yang kita buat
mItems.add(md);
} catch (JSONException e) {
e.printStackTrace();
}
}
mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
Log.d("volley", "error : " + error.getMessage());
}
});
Controller.getInstance().addToRequestQueue(arrayRequest);
}
}
Unreachable statement
That's expected error, because you're stopping the onCreateView method after you're giving it a return statement:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// You've already close the method when you're giving a return
return inflater.inflate(R.layout.fragment_kecamatan, container, false);
// so this won't be reachable, hence the unreachable error raised.
mRecyclerView = (RecyclerView) mRecyclerView.findViewById(R.id.list_data);
...
}
So, you either need to inflate the Layout first and bind the view then return the inflated view or move the view binding after the return statement to another method.
As mentioned by ישו אוהב אותך, You're returning the inflated view immediately. keep a reference to the inflated view and return it at the end. Also, you probably want to use findViewById on the inflated view and not on mRecyclerView.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_kecamatan, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.list_data);
mItems = new ArrayList<>();
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
mAdapter = new AdapterProcess(KecamatanFragment.this, mItems);
mRecyclerView.setAdapter(mAdapter);
loadjson();
return view;
}
I am a beginner at the android studio. I have parsed some JSON data from the server. I want to implement these data in a viewpager. I got A sample viewpager code. But when I apply these JSON data to list it shows cannot resolve constructor. My Viewpager code is below.
My JSON Fetching code
public class MainActivity extends AppCompatActivity {
// Constants
private static final String TAG = MainActivity.class.getSimpleName();
// UI Components
private VerticalViewPager mVvpMainPager;
// Other objects
private ViewPagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mVvpMainPager = findViewById(R.id.activity_main_vvp_main_pager);
setupViewPager();
}
private void setupViewPager() {
mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
for (BeanNews news : generateSampleNewsData()) {
mPagerAdapter.addFragment(PagerFragment.newInstance(news), "News " + news.getNewsId());
}
mVvpMainPager.setAdapter(mPagerAdapter);
mVvpMainPager.setOffscreenPageLimit(generateSampleNewsData().size());
}
private ArrayList<BeanNews> generateSampleNewsData() {
String url ="http://maranamassapp.cf/json_getdata.php";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("server_response");
for(int i = 0; i < jsonArray.length(); i++){
JSONObject ser =jsonArray.getJSONObject(i);
String creatorname = ser.getString("head");
String imageUrl = ser.getString("image");
String cat = ser.getString("content");
String postdate = ser.getString("weburl");
String dateall = ser.getString("date");
BeanNews news = new BeanNews(creatorname,imageUrl,cat,postdate,dateall);
ArrayList<BeanNews> newsList = new ArrayList<>();
newsList.add(news);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
return newsList;
}
Check this about ViewPager:
Layout manager that allows the user to flip left and right through
pages of data. You supply an implementation of a PagerAdapter to
generate the pages that the view shows.
ViewPager is most often used in conjunction with Fragment, which is a
convenient way to supply and manage the lifecycle of each page.
Now, you'll need a RecyclerView or a ListView inside ViewPager xml layout file to show the data. So, you'll need Fragment inside ViewPager, a RecyclerView || ListView inside Fragment then showing data or adding to RecyclerView adapter.
Can't actually pass list of items(from json in your case) to ViewPager to show on the view in Android.
I'm developing an Android app that shows movie posters for top rated movies. I want to build this by using Retrofit 2. However, I keep getting the error 'Service methods cannot return void'. Here's the stack trace:
FATAL EXCEPTION: main
Process: com.hfad.popularmovies, PID: 17921
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hfad.popularmovies/com.hfad.popularmovies.MainActivity}: java.lang.IllegalArgumentException: Service methods cannot return void.
for method MoviesAPI.getFeedPopular
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalArgumentException: Service methods cannot return void.
I have created a POJO containing the fields I need & the necessary interface containing the get request =>
public interface MoviesAPI {
#GET("/movie/top_rated?api_key=XXXXXXX")
void getFeedTopRated(Callback <List<Movie>> response);
#GET("/movie/popular?api_key=XXXXXXX")
void getFeedPopular(Callback<List<Movie>> response);
}
Here's the fragment that should display the posters through a RecyclerView:
public class TopRatedFragment extends Fragment {
private static final String ENDPOINT = "http://api.themoviedb.org/3/";
private PosterAdapter adapter;
private List<Movie> movieList;
public TopRatedFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RecyclerView recyclerView = (RecyclerView) inflater.inflate(R.layout.fragment_top_rated, container, false);
adapter = new PosterAdapter(getActivity());
recyclerView.setAdapter(adapter);
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(layoutManager);
getTopRatedMovies();
return recyclerView;
}
private void getTopRatedMovies() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.build();
MoviesAPI api = retrofit.create(MoviesAPI.class);
api.getFeedTopRated(new Callback<List<Movie>>() {
#Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
movieList = response.body();
for (Movie movie : movieList) {
movie.getPoster_path(); //I get the same error when I use
}
}
#Override
public void onFailure(Call<List<Movie>> call, Throwable t) {
}
});
}
}
Please, let me know if I should provide more code or background information.
Your interface method needs to return an object from the type
Call<Expected Result Object>
For example
#GET("/movie/top_rated?api_key=XXXXXXX")
Call<List<Movie>> getFeedTopRated();
And in the method you need to write the function as following:
api.getFeedTopRated().enque(new Callback<List<Movie>>() { /* */ });
I have a listview inside a fragment showing weather data(image,temperature and weather description). I fetch the data from here
When I rotate the emulator though I get a crash.:(. Here is my code. I use the setRetainedInstance but with out any result. Somehow I need to save and restore the asynchronous data I get,but I don't know how.
public class ForecastFragment extends Fragment{
ListView listView;
List<WeatherForecastData> WeatherForecastDataList;
String IMG_URL = "http://api.openweathermap.org/img/w/";
Fragment fragment;
public ForecastFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Inflate xml view and convert it to a View object
View rootView = inflater.inflate(R.layout.fragment_forecast, container, false);
//Initialise ListView.
listView = (ListView) rootView.findViewById(R.id.listView);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String temp = WeatherForecastDataList.get(position).getWeatherTemperature();
Toast.makeText(getActivity(),temp+" Have a nice day",Toast.LENGTH_SHORT).show();
}
});
return rootView;
}
//Now we are ready for further processing
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
requestData("http://api.openweathermap.org/data/2.5/forecast/daily?lat=50.09&lon=14.42&cnt=9&&units=metric&mode=json");
}
//We create a MyTask object,and execute the async. thread with the specified url which is shown just above.
private void requestData(String uri) {
MyTask task = new MyTask();
task.execute(uri);
}
//AsyncTask that will do the asynchronous threading. It displays the weather's icon,description
//and temperature in the main thread via the OnPostExecute(...) method.
private class MyTask extends AsyncTask<String, String, List<WeatherForecastData>> {
#Override
protected void onPreExecute() {
//Used to initialise Views such as Progress Bars which are not needed for this
//project.
}
#Override
protected List<WeatherForecastData> doInBackground(String... params) {
//Read the url,specify the METHOD GET, and store it in content.
String content = HttpManager.getData(params[0]);
//JSON parsing of the openweather api's response. It is not hard,but I had to use the
//debugger quite a lot to make sure that I deserialise the correct JSON values into Strings.
WeatherForecastDataList = WeatherJSONParser.parseFeed(content);
//Fetching the url image
for (WeatherForecastData d : WeatherForecastDataList) {
try {
String imageUrl = IMG_URL +d.getPhoto();
InputStream in = (InputStream) new URL(imageUrl).getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
//Is it deprecated?
d.setBitmap(bitmap);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return WeatherForecastDataList;
}
//WeatherForecastData is the Object that contains all that instances we want to display.
#Override
protected void onPostExecute(List<WeatherForecastData> result) {
if (result == null) {
Toast.makeText(getActivity(), "There is some wrong,and data can not be displayed", Toast.LENGTH_LONG).show();
return;
}
WeatherForecastDataList = result;
//Display the ListView.
WeatherAdapter adapter = new WeatherAdapter(getActivity(), R.layout.weather_row,WeatherForecastDataList);
listView.setAdapter(adapter);
}
}
}
Here is my logcat.
08-01 19:45:59.857 21260-21260/com.theotziomakas.weatherapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at android.widget.ArrayAdapter.init(ArrayAdapter.java:310)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:153)
at com.theotziomakas.weatherapp.Fragments.WeatherAdapter.<init>(WeatherAdapter.java:34)
at com.theotziomakas.weatherapp.Fragments.ForecastFragment$MyTask.onPostExecute(ForecastFragment.java:144)
at com.theotziomakas.weatherapp.Fragments.ForecastFragment$MyTask.onPostExecute(ForecastFragment.java:98)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
You need to implement onSaveInstanceState to save the data, then retrieve it in onCreateView
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("YourVariableName", yourVariable);
super.onSaveInstanceState(savedInstanceState);
}
Then in onCreateView
if (savedInstanceState != null) {
yourVariable = savedInstanceState.getString("YourVariableName");
}
Check out the documentation for more info
I'm having problems to implement an onclick to the items I have in my list. the error is below:
06-14 16:15:43.861 11651-11651/wk.gon250.dublinbike E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: wk.gon250.dublinbike, PID: 11651
java.lang.RuntimeException: Don't call setOnClickListener for an AdapterView. You probably want setOnItemClickListener instead
at android.widget.AdapterView.setOnClickListener(AdapterView.java:778)
at tab.Tab2.onCreateView(Tab2.java:67)
The code of my class is:
public class Tab2 extends Fragment
{
static ListView listView;
static CustomAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.tab_2, container, false);
String Url = "http://mypath";
RequestQueue queue = Volley.newRequestQueue(getActivity());
final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "Please, Wait", "Loading..");
listView = (ListView) v.findViewById(R.id.listViewT_stations);
JsonObjectRequest req = new JsonObjectRequest(Url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Gson gson = new Gson();
JSONObject jsonNetwork = new JSONObject(response.getString("network"));
JSONArray stationsArray = jsonNetwork.getJSONArray("stations");
StationJson[] stations = gson.fromJson(stationsArray.toString(), StationJson[].class);
adapter = new CustomAdapter(getActivity(), stations, R.layout.station_item);
listView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
progressDialog.cancel();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Manage Error
progressDialog.cancel();
}
});
queue.add(req);
listView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return v;
} }
I can't no use a listFragment, so any sugestion? How can I implement a onclick to the items I have to open a new view? and what is the best practice?
Thanks!!
The error message says:
Don't call setOnClickListener for an AdapterView. You probably want setOnItemClickListener instead
The OnClickListener is meant for click events on whole views. In an AdapterView, you usually want to register click events for each item separately. For this you need to use OnItemClickListener.