I need some help with the logic to my problem. I have searched already on here for posts discussing similar issues, however haven't yet had success in fixing my problem so I don't wish to make this a duplicate post.
I am working on an app and I am having issues in displaying parsed JSON Data in a recycler view within a Slide Tab Fragment. I have a Sliding Tabs on my main activity with five fragments in total, one for each tab (5 tabs in total). What I want to do for the third tab is to display a recycler view with parsed JSON data that is being retrieved from the server. I have the same functionality within an activity for my other recyclerviews and they work fine. I was just struggling slightly on how to achieve this inside a fragment. I am providing the below code for troubleshooting and debugging purposes:
Here is the code to my MainActivity.java
public class MainActivity extends BaseActivity {
private ViewPager mPager;
private SlidingTabLayout mTabs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// To track statistics around application
ParseAnalytics.trackAppOpened(getIntent());
// inform the Parse Cloud that it is ready for notifications
ParseInstallation.getCurrentInstallation().saveInBackground();
//Calling Activate Toolbar method
activateToolBar();
mPager = (ViewPager) findViewById(R.id.pager);
//Setting the Adapter on the view pager first. Passing the fragment manager through as an argument
mPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
//Setting the custom Tab View as the Sliding Tabs Layout
mTabs.setCustomTabView(R.layout.custom_tab_view, R.id.tabText);
mTabs.setDistributeEvenly(true);
//mTabs.setSelectedIndicatorColors(getResources().getColor(R.color.tabIndicatorColour));
mTabs.setBackgroundColor(getResources().getColor(R.color.basePrimaryBackgroundColour));
//Setting the ViewPager as the tabs
mTabs.setViewPager(mPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
//int id = item.getItemId();
//noinspection SimplifiableIfStatement
//if (id == R.id.action_settings) {
// return true;
//}
return super.onOptionsItemSelected(item);
}
class MyPagerAdapter extends FragmentPagerAdapter {
String[] tabs;
public MyPagerAdapter(FragmentManager fm) {
super(fm);
//Initialising the strings array of the tabs
tabs = getResources().getStringArray(R.array.tabs);
}
/*
//Setting up integer array of icons
int icons[] = {R.drawable.about_us, R.drawable.campus, R.drawable.events, R.drawable.learning, R.drawable.sewa};
//Defined from strings.xml
String[] tabText = getResources().getStringArray(R.array.tabs);
public MyPagerAdapter(FragmentManager fm) {
super(fm);
//Initialising the strings array of tabs
tabText = getResources().getStringArray(R.array.tabs);
}
*/
#Override
public Fragment getItem(int position) {
if (position == 0) // if the position is 0 we are returning the First tab
{
Tab1 tab1 = new Tab1();
return tab1;
} else if (position == 1)
{
Tab2 tab2 = new Tab2();
return tab2;
} else if (position == 2)
{
Tab3 tab3 = new Tab3();
return tab3;
} else if (position == 3)
{
Tab4 tab4 = new Tab4();
return tab4;
} else
{
Tab5 tab5 = new Tab5();
return tab5;
}
}
#Override
public CharSequence getPageTitle(int position) {
//Return the text of the position clicked and display this as the title for the tab
return tabs[position];
}
#Override
public int getCount() {
return 5;
}
}
}
This is the code for my RecyclerViewAdapterEvents.java
public class RecyclerViewAdapterEvents extends RecyclerView.Adapter<RecyclerViewAdapterEvents.MyViewHolder> {
private LayoutInflater inflater;
//private EventsActivity activity;
private List<JSONEventsItem> data = Collections.emptyList();
private Context mContext;
//Variable for the on click Listener
private ClickListener clickListener;
//Passing in the array list argument
public RecyclerViewAdapterEvents(Context context, List<JSONEventsItem> data) {
this.mContext = context;
//this.activity = activity;
inflater = LayoutInflater.from(context);
//Setting the array list data to the argument passed in
this.data = data;
}
#Override
public RecyclerViewAdapterEvents.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//Inflating the row and getting the root of view of the custom row (Linear Layout)
View view = inflater.inflate(R.layout.custom_row, parent, false);
//Passing the root view through as an argument
MyViewHolder holder = new MyViewHolder(view);
//Returning the view holder
return holder;
}
#Override
public void onBindViewHolder(RecyclerViewAdapterEvents.MyViewHolder holder, int position) {
//This will get the current position of the JSONEventItem object from the array
JSONEventsItem eventsItem = data.get(position);
//Setting the event name to the name of the event retrieved from the Database (converting from JSON)
holder.eventName.setText(Html.fromHtml(eventsItem.getEventName()));
}
#Override
public int getItemCount() {
return (null != data ? data.size() : 0);
}
public void setClickListener(ClickListener clicklistener) {
this.clickListener = clicklistener;
}
public interface ClickListener {
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView eventName;
public MyViewHolder(View itemView) {
super(itemView);
//Here setting the id of the textview in the recycler view holder to be the list view from the custom_row xml
eventName = (TextView) itemView.
findViewById(R.id.listText);
}
}
}
Here is the class file for Tab3 Fragment, Tab3.java
public class Tab3 extends Fragment implements RecyclerViewAdapterEvents.ClickListener{
private RecyclerView mRecyclerView;
//Creating an instance of the adapter object
private RecyclerViewAdapterEvents adapter;
private List<JSONEventsItem> EventsList;
private String jsonString = "";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.tab_3,container,false);
//Instantiating the recycler view as defined in tab_1
mRecyclerView = (RecyclerView) v.findViewById(R.id.about_us_recycler_view);
//Adding item decoration. Recycler view divider
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
//Initialising the adapter - Passing in the activity and the getData method
adapter = new RecyclerViewAdapterEvents(getActivity(), EventsList);
//Here passing in the click listener into the Adapter. 'this' signifies that it is the fragment that handles the click listener.
//This is possible as the on Click Listener interface is being implemented.
adapter.setClickListener(this);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
//Setting the Layout
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//Downloading data from below url (Universal Resource Locator) to obtain data from the Admin database
final String url = "http://dbchudasama.webfactional.com/jsonscript.php";
new AsyncHTTPTask().execute(url);
return v;
}
public class AsyncHTTPTask extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
jsonString = response.toString();
parseResult();
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d("Exception Caught", e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
//adapter.getItemCount();
if (result == 1) {
//Intent intent = getIntent();
//intent.getSerializableExtra("JSON Admin");
//Initialising the adapter - Passing in the activity and the parsed Admin Team List
adapter = new RecyclerViewAdapterEvents(getActivity(), EventsList);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
} else {
Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
}
//This method will parse the RAW data downloaded from the server
private void parseResult() {
try {
JSONArray AdminArrays = new JSONArray(jsonString);
EventsList = new ArrayList<>();
for (int i = 0; i < AdminArrays.length(); i++) {
JSONObject AdminArrayObject = AdminArrays.getJSONObject(i);
JSONEventsItem item = new JSONEventsItem();
item.setEventName(AdminArrayObject.getString("eventName"));
this.EventsList.add(item);
Log.e("Event Name", AdminArrayObject.getString("eventName"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
The Tab3.java code has crashed all my other tabs and is giving a null pointer exception on the the getActivity() method, as this is being performed on a null object reference. Could I just declare an activity of type EventsActivity and pass this through instead? Also So I am slightly unsure how to resolve this. For completeness I have also written the same code within an activity EventsActivity.java which I know will work. It is just getting it to run within the fragment.
public class EventsActivity extends BaseActivity implements RecyclerViewAdapterEvents.ClickListener {
private RecyclerView mRecyclerView;
//Creating an instance of the adapter object
private RecyclerViewAdapterEvents adapter;
private List<JSONEventsItem> EventsList;
private EventsActivity activity;
private String jsonString = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_3);
//Calling Activate Toolbar method (with the Back button enabled)
activateToolbarWithHomeEnabled();
//Instantiating the recycler view as defined in admin_team
//mRecyclerView = (RecyclerView) findViewById(R.id.events_recycler_view);
//Adding item decoration. Recycler view divider
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
//Initialising the adapter - Passing in the activity and the parsed Events List
adapter = new RecyclerViewAdapterEvents(this, EventsList);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
//Setting the Layout
//mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//Downloading data from below url (Universal Resource Locator) to obtain data from the Admin database
final String url = "http://dbchudasama.webfactional.com/jsonscript.php";
new AsyncHTTPTask().execute(url);
}
public class AsyncHTTPTask extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
jsonString = response.toString();
parseResult();
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d("Exception Caught", e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
//adapter.getItemCount();
if (result == 1) {
//Intent intent = getIntent();
//intent.getSerializableExtra("JSON Admin");
//Initialising the adapter - Passing in the activity and the parsed Admin Team List
adapter = new RecyclerViewAdapterEvents(EventsActivity.this, EventsList);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
} else {
Toast.makeText(EventsActivity.this, "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
}
//This method will parse the RAW data downloaded from the server
private void parseResult() {
try {
JSONArray AdminArrays = new JSONArray(jsonString);
EventsList = new ArrayList<>();
for (int i = 0; i < AdminArrays.length(); i++) {
JSONObject AdminArrayObject = AdminArrays.getJSONObject(i);
JSONEventsItem item = new JSONEventsItem();
item.setEventName(AdminArrayObject.getString("eventName"));
this.EventsList.add(item);
Log.e("Event Name", AdminArrayObject.getString("eventName"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Here is my crash log from Logcat:
11-09 18:56:21.587 2961-2961/com.divyeshbc.NHSF E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.divyeshbc.NHSF, PID: 2961
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.addItemDecoration(android.support.v7.widget.RecyclerView$ItemDecoration)' on a null object reference
at com.divyeshbc.NHSF.tabs.events.Tab3.onCreateView(Tab3.java:53)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1105)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:551)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:513)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:494)
at com.divyeshbc.NHSF.tabs.SlidingTabLayout$TabClickListener.onClick(SlidingTabLayout.java:324)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Where am I going wrong? Any guidance will be highly helpful :).
Thanks
Related
This question already has answers here:
Passing Data Between Fragments to Activity
(7 answers)
Closed 5 years ago.
I am new to Java. The activity is to receive an ID and reuse that ID to get the detail of the recipe with a Recipe API. I am using three tabs to show different content. The problem that I could not figure out is that the first (description tab) and the third (step tab) can receive the string from main activity, but the second tab (ingredient tab) always receives null value from the main activity. Also, The string does not show on the first tab immediately when I run the activity. It only shows after I click on the third tab and come back to the first one.
Activity
public class SearchHomeResultActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
public String RecipeId = "479101";
public String SInstruction;
public String SIngredients;
public String STitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
new CallMashapeAsync().execute(RecipeId);
}
public class CallMashapeAsync extends AsyncTask<String, Integer, HttpResponse<JsonNode>> {
protected HttpResponse<JsonNode> doInBackground(String... msg) {
HttpResponse<JsonNode> request = null;
try {
request = Unirest.get("https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/" + msg[0] + "/information")
.header("X-Mashape-Key", "EulyPgSat2mshhTi8JJxY40UEWzdp1mMmEGjsnrbQq1AB0vuOY")
.header("X-Mashape-Host", "spoonacular-recipe-food-nutrition-v1.p.mashape.com")
.asJson();
} catch (UnirestException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return request;
}
protected void onProgressUpdate(Integer... integers) {
}
protected void onPostExecute(HttpResponse<JsonNode> response) {
String answer = response.getBody().toString();
try {//get all response
JSONObject obj = new JSONObject(answer);
//get ingredients
String Ringredient = obj.getString("extendedIngredients");
List<String> terms1 = new ArrayList<String>();
JSONArray ing = new JSONArray(Ringredient);
for (int i = 0; i < ing.length(); i++) {
JSONObject ING1 = ing.getJSONObject(i);
String Ostr = ING1.getString("originalString");
terms1.add(Ostr);
}
String listString = "";
for (String s : terms1) {
listString += s + "\n";
}
//get instructions
String Rid1 = obj.getString("instructions");
//get title
String Rid2 = obj.getString("title");
SInstruction = Rid1;
SIngredients = listString;
STitle = Rid2;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
public String getIns() {
//
return SInstruction;
}
public String getIngredients() {
//
return SIngredients;
}
public String getRTitle() {
//
return STitle;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
descriptionTab tab1 = new descriptionTab();
return tab1;
case 1:
IngredientsTabActivity tab2 = new IngredientsTabActivity();
return tab2;
case 2:
StepTabActivity tab3 = new StepTabActivity();
return tab3;
}
return null;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
}
}
Fragment
public class StepTabActivity extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.step_layout, container, false);
SearchHomeResultActivity getData = (SearchHomeResultActivity) getActivity();
String Rid = getData.getIngredients();
TextView txt = rootView.findViewById(R.id.name);
txt.setText(Rid);
return rootView;
}
This is the code of the Step (the third) fragment. Other two are the same, but just calling different methods to get different strings for the TextView.
Please help me. Thank you so much!
You can create a constructor like method called newInstance in your fragment as below,
public static FragmentName newInstance(String str) {
Bundle args = new Bundle();
FragmentName fragment = new FragmentName();
fragment.setArguments(args);
resID = str;
return fragment;
}
define your "resID" as global variable and use it in fragment's onCreate method.
and from activity when u are adding fragment to viewPager adapter do like this
adapter.addFrag(FragmentName.newInstance(resID), "fragment_name");
I am using a loader and a OkHttp client to get data from a news API and populate the data in a recycler view. I used a progress bar to show until the the loader is finished loading the data . But all I see is the progress bar, the recycler view is not showing up.
Please help me
MainActivity.java
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<ArrayList<News>> {
private static final int LOADER_ID = 1 ;
private String url = "https://newsapi.org/v1/articles?source=the-times-of-india&sortBy=latest&apiKey=<API KEY>";
private ProgressBar progressBar;
private NewsAdapter mAdapter;
private RecyclerView recList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
progressBar.setVisibility(View.VISIBLE);
recList = (RecyclerView) findViewById(R.id.cardList);
recList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recList.setLayoutManager(llm);
recList.setHasFixedSize(true);
getSupportLoaderManager().initLoader(LOADER_ID , null , this);
}
#Override
public Loader<ArrayList<News>> onCreateLoader(int id, Bundle args) {
return new AsyncTaskLoader<ArrayList<News>>(this) {
#Override
public ArrayList<News> loadInBackground() {
return makeConnectionAndParseData(url);
}
};
}
#Override
public void onLoadFinished(Loader<ArrayList<News>> loader, ArrayList<News> data) {
progressBar.setVisibility(View.INVISIBLE);
mAdapter = new NewsAdapter(data);
recList.setAdapter(mAdapter);
// The data is brought back here after the network call is executed in the variable data.
// Update the recycler view here to show the list of news
// Take care of exception cases like no network connection , invalid url and other extreme cases
}
#Override
public void onLoaderReset(Loader<ArrayList<News>> loader) {
// Reset the recycler view . The UI should not show recycler view when the loader is reset
// Update the UI with a text view to let the user know about the error
}
private String makeNetworkConnection(String url)
{
OkHttpClient client = new OkHttpClient();
try {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private ArrayList<News> parseJsonIntoArrayList(String json)
{
final ArrayList<News> newsArrayList;
try {
newsArrayList = null;
JSONObject object = new JSONObject(json);
JSONArray articles = object.getJSONArray("articles");
for (int i=0 ; i<articles.length() ; i++)
{
JSONObject articleObjects = articles.getJSONObject(i);
String author = articleObjects.getString("author");
String title = articleObjects.getString("title");
String desc = articleObjects.getString("description");
String imageUrl = articleObjects.getString("imageUrl");
String clickableUrl = articleObjects.getString("url");
newsArrayList.add(new News(title,desc,imageUrl,clickableUrl,author));
}
return newsArrayList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
private ArrayList<News> makeConnectionAndParseData(String url)
{
String jsonResponse = makeNetworkConnection(url);
return parseJsonIntoArrayList(jsonResponse);
}}
NewsAdapter.java
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsHolder> {
ArrayList<News> mNewsData;
public NewsAdapter(ArrayList<News> newsData)
{
mNewsData = newsData;
}
public class NewsHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView titleTv , descTv ;
private ImageView newsImageView;
public NewsHolder(View itemView) {
super(itemView);
titleTv = (TextView) itemView.findViewById(R.id.newsTitle);
descTv = (TextView) itemView.findViewById(R.id.newsDesc);
newsImageView = (ImageView) itemView.findViewById(R.id.newsImage);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// Handle the click item here.
}
}
#Override
public NewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View inflatedView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item , parent , false);
return new NewsHolder(inflatedView);
}
#Override
public void onBindViewHolder(NewsHolder holder, int position) {
News news = mNewsData.get(position);
holder.titleTv.setText(news.getNewsTitle());
holder.descTv.setText(news.getNewsSubtitle());
String imageUrl = news.getImageUrl();
Picasso.with(holder.newsImageView.getContext())
.load(imageUrl)
.into(holder.newsImageView);
}
#Override
public int getItemCount() {
return mNewsData.size();
}}
In android monitor , there was
01-10 14:55:59.319 10318-10318/com.sriram.news E/RecyclerView: No adapter attached; skipping layout
Please tell me where I have gone wrong
And is my implementation of the recycler view correct? I'm still confused about recycler view.
Thanks in advance
Place
mAdapter = new NewsAdapter();
recList.setAdapter(mAdapter);
above
recList.setLayoutManager(llm);
recList.setHasFixedSize(true);
and fix NewsAdapter.java
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsHolder> {
ArrayList<News> mNewsData;
// remove constructor
public void addAll(List<News> newsData) {
mNewsData = newsData;
}
...
}
MainActivity.java
#Override
public void onLoadFinished(Loader<ArrayList<News>> loader, ArrayList<News> data) {
progressBar.setVisibility(View.INVISIBLE);
mAdapter.addAll(data);
mAdapter.notifyDataSetChanged();
}
I am working on parsing JSON output from server using volley. I have created a customList extending BaseAdapter,When i click on the row i need to call another activity which show remaining data of json.
Here is the JSON output
{
"id":"12",
"company_name":"Kartik",
"company_logo":"",
"job_title":"php developer",
"experience":"2 to 3",
"location":"city",
"walkin_date":"5:11:2016",
"salary":"3.4-4.4L pa",
"qualification":"B.E",
"address":""
}
Here is the code of CustomList view
`public class CustomLIstAdapter extends BaseAdapter
{
private Activity activity;
private LayoutInflater inflater;
private List<Movie> movieList;
ImageLoader imageLoader = Controller.getInstance().getImageLoader();
public CustomLIstAdapter(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieList = movieItems;
}
public int getCount() {
return movieList.size();
}
public Object getItem(int location) {
return movieList.get(location);
}
// this will retrive the current touch id
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
if (imageLoader == null)
imageLoader = Controller.getInstance().getImageLoader();
NetworkImageView thumbnail = (NetworkImageView) convertView.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView rating = (TextView) convertView.findViewById(R.id.rating)
TextView genre = (TextView) convertView.findViewById(R.id.genre);
TextView year = (TextView)convertView.findViewById(R.id.releaseYear);
Movie m = movieList.get(position);
thumbnail.setImageUrl(m.getCompanyLogo(), imageLoader)
title.setText(m.getCompanyName());
rating.setText(m.getTitle());
year.setText("Walking Date : " + m.getWalkinDate());
return convertView;
}
}
Here is the main Activity code
`public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final String url="http://10.0.3.2:80/demoApi/api/users";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private ListView listView;
private CustomLIstAdapter adapter;
private SwipeRefreshLayout swipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setVisibility(View.INVISIBLE);
// accessing the layout of the sumeeth refresh.
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
listView = (ListView) findViewById(R.id.list);
adapter = new CustomLIstAdapter(this, movieList);
listView.setAdapter(adapter);
/*Testing on swipe listener.*/
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
retriveDataJob();
}
});
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
//call which method to refresh.
retriveDataJob();
}
});
}
private void retriveDataJob() {
//this method will call the server and update the list of things
swipeRefreshLayout.setRefreshing(true);
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Movie movie = new Movie();
movie.setCompanyName(obj.getString("company_name"));
movie.setCompanyLogo(obj.getString("company_logo"));
movie.setTitle(obj.getString("job_title"));
movie.setWalkinDate(obj.getString("walkin_date"));
movie.setLocation(obj.getString("location"));
movieList.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
//stop the refresher
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
//stopHere
swipeRefreshLayout.setRefreshing(false);
}
});
// Adding request to request queue
Controller.getInstance().addToRequestQueue(movieReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}`
Here is some hint for your confusion so define your response of json in fragment activity as public
i.e
public MyJsonresponse mResponse;
and than implement listener to your listview
lv.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3)
{
//Call Your fragment to show full json data detail.
// do what you intend to do on click of listview row
}
});
Create one method in your fragment.ex
private MainFragmentActivity mainActivity() {
return ((MainFragmentActivity) getActivity());
}
after that you can call your fragment activity response inside your second screen or fragment like mainActivity().mResponse
This is it
Regards.
lv.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3)
{
//get all the data from list and send to next activity where you can view your data as you want:
Intent i1=new Intent(A.this, B.class);
i1.putExtra("data", lv.get(position).getData());
startActivity(i1);
}
});
Now in new Activity get the data:
String data=getIntent.getStringExtra("data");
I have made a custom Adapter and populate it with the data. I have used Logcat to see whether the array i'm passing to custom Adapter class contains the data and it does.
The error i got is following. It occurs when this CategoryBlog is created. Activity is created but it does not contain list view
exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
'mainblogpost' contains the array with all the data i want to populate with.
'MainListActivityAdapter' is the Adapter Class.
'Category_Blogs' is the class where i want to set the list view.
Category_Blog.java
I don't add import statement. there is no error in it
public class Category_Blogs extends AppCompatActivity implements AbsListView.OnItemClickListener {
public static final String TAG = MainActivity.class.getSimpleName();
public final static String EXTRA_MESSAGE = "com.example.talha.appforblog.MESSAGE";
List<StackOverflowXmlParser.Entry> mainBlogPost = new ArrayList<StackOverflowXmlParser.Entry>();
private ListAdapter mAdapter;
private AbsListView mListView;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category__blogs);
//Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
//setSupportActionBar(toolbar);
Intent intent = getIntent();
String message = intent.getStringExtra(Tab2.EXTRA_MESSAGE);
String link = message.trim() + "?feed=titles";
Log.d("ye category click krne par next activity me ye link bnta hy parsing ke liye",link);
loadPage(link);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_category__blogs, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void loadPage(String link) {
Log.d(TAG, "loadpage me a gae nh");
// if((sPref.equals(ANY)) && (wifiConnected || mobileConnected)) {
new DownloadXmlTask(this).execute(link);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
private class DownloadXmlTask extends AsyncTask<String, Void, List<StackOverflowXmlParser.Entry>> {
private Context mContext;
public DownloadXmlTask(Context context) {
mContext = context;
}
#Override
protected List<StackOverflowXmlParser.Entry> doInBackground(String... urls) {
try {
return loadXmlFromNetwork(urls[0]);
} catch (Exception e) {
Log.d("test", "" + e);
}
return null;
}
#Override
protected void onPostExecute(List<StackOverflowXmlParser.Entry> results) {
if (results != null) {
try {
String title, link, image, pubDate;
Log.d("test", "onpost");
// custom array adapter
ArrayList<HashMap<String, String>> blogPosts = new ArrayList<HashMap<String, String>>();
for (StackOverflowXmlParser.Entry result : results) {
title = result.title;
link = result.link;
image = result.image;
pubDate = result.pubDate;
HashMap<String, String> blogPost = new HashMap<String, String>();
blogPost.put("link", link);
blogPost.put("title", title);
blogPost.put("image", image);
blogPost.put("pubDate", pubDate);
blogPosts.add(blogPost);
}
// copying to main item List array
for (int i = 0; i < results.size(); i++) {
mainBlogPost.add(results.get(i));
}
Log.d("fff", results.get(1).pubDate);
MainListActivityAdapter mAdapter =
new MainListActivityAdapter(Category_Blogs.this, mainBlogPost);
listView.setAdapter(mAdapter);
//((AdapterView<ListAdapter>) mListView).setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks
mListView.setOnItemClickListener(Category_Blogs.this);
}
catch (Exception e){
Log.d("test", "exception: "+e);
}
}
}
private List<StackOverflowXmlParser.Entry> loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {
InputStream stream = null;
// Instantiate the parser
StackOverflowXmlParser stackOverflowXmlParser = new StackOverflowXmlParser();
List<StackOverflowXmlParser.Entry> entries = null;
String title = null;
String url = null;
try {
//opening the connection and fetching
stream = downloadUrl(urlString);
entries = stackOverflowXmlParser.parse(stream);
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (Exception e) {
Log.d("test", "" + e);
} finally {
if (stream != null) {
stream.close();
}
}
for (StackOverflowXmlParser.Entry entry : entries) {
Log.d("aaa",entry.pubDate);
}
return entries;
}
private InputStream downloadUrl(String urlString) throws IOException {
java.net.URL url = new java.net.URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
return conn.getInputStream();
}
}
}
MainListActivityAdapter.java
public class MainListActivityAdapter extends BaseAdapter {
private Activity activity;
List<StackOverflowXmlParser.Entry> mainBlogPost = new ArrayList<StackOverflowXmlParser.Entry>();
private static LayoutInflater inflater = null;
public MainListActivityAdapter(Activity a, List<StackOverflowXmlParser.Entry> main) {
activity = a;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mainBlogPost = main;
}
public int getCount() {
return mainBlogPost.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
Log.d("test", "fetching" + position);
String tit = mainBlogPost.get(position).title;
String cate = mainBlogPost.get(position).pubDate;
String pub = mainBlogPost.get(position).pubDate;
String image_url = "http://download.androidhive.info/img/btn_fb_login.png";
if (convertView == null)
vi = inflater.inflate(R.layout.list_row, null);
TextView title = (TextView) vi.findViewById(R.id.title); // title
TextView cat = (TextView) vi.findViewById(R.id.category); // category
ImageView image = (ImageView) vi.findViewById(R.id.list_image); // image
TextView publish = (TextView) vi.findViewById(R.id.pubDate); // publish date
// Setting all values in listview
title.setText(tit);
cat.setText(cate);
publish.setText(pub);
Glide.with(activity)
.load(image_url)
.into(image);
return vi;
}
}
Activity_category_blog.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent"
android:layout_height="wrap_content" tools:context="com.example.talha.test_fragement.Category_Blogs"
xmlns:ads="http://schemas.android.com/apk/res-auto">
<include layout="#layout/tool_bar" />
<FrameLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#layout/tool_bar">
<ListView android:id="#android:id/list" android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/adView" android:divider="#b5b5b5"
android:dividerHeight="1dp"
android:layout_alignParentBottom="true"
/>
<TextView android:id="#android:id/empty" android:layout_width="match_parent"
android:layout_height="match_parent" android:gravity="center"
android:layout_gravity="right|top" />
</FrameLayout>
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category__blogs);
listView = (ListView) findViewById(R.id.lvID);//where lvID is id from your listview placed in activity_category__blogs layout.
You fail to initialize the listview.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category__blogs);
//Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
**listView = (ListView) findViewById(R.id.list);**
//setSupportActionBar(toolbar);
Intent intent = getIntent();
String message = intent.getStringExtra(Tab2.EXTRA_MESSAGE);
String link = message.trim() + "?feed=titles";
Log.d("ye category click krne par next activity me ye link bnta hy parsing ke liye",link);
loadPage(link);
}
I'm a bit new to posting on StackOverflow. I've done a whole bunch of searching, and I can't seem to find an answer that helps me solve my specific problem.
I am trying to parse this particular Json: https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=fuzzy%20monkey%27
I'm new to Json, and I am using Google Gson in order to parse it. It compiles fine. However it doesn't seem as if my Java classes are being populated with the proper info from the Json (I keep getting NullPointerExceptions), which is probably due to my lack of knowledge about Json. In this code, the NullPointerException comes specifically from the final int N = response.results.size() line from my Main Activity.
My Main Activity:
public class MainActivity extends ActionBarActivity {
public static InputStream json;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
ResponseData response = new ResponseData();
new JsonAsync(this, response).execute();
final int N = response.results.size();
final TextView[] myTextViews = new TextView[N]; // create an empty array;
for (int i = 0; i < N; i++) {
// create a new textview
final TextView textView = new TextView(this);
textView.setText("Image Name:" + response.results.get(i).titleNoFormatting);
RelativeLayout myLayout = (RelativeLayout) findViewById(R.id.container);
// add the textview to the linearlayout
myLayout.addView(textView);
// save a reference to the textview for later
myTextViews[i] = textView;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
/**
* Async Task for Grabbing Json Data
*
*/
private static class JsonAsync extends AsyncTask<Void, Void, ResponseData> {
private String text;
public InputStream stream;
private Activity activity;
private ResponseData response;
public JsonAsync(Activity activity, ResponseData response) {
this.activity = activity;
this.response = response;
}
#Override
protected ResponseData doInBackground(Void...params) {
try {
URL url = new URL("https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=fuzzy%20monkey%27");
InputStream stream = url.openStream();
Gson gson = new Gson();
String json = convertStreamToString(stream);
ResponseData response = gson.fromJson(json, ResponseData.class);
return response;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(ResponseData result) {
super.onPostExecute(result);
}
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
}
My Result Class:
public class Result {
public int width;
public int height;
public String visibleUrl;
public String titleNoFormatting;
public URL url;
public Result () {
}
}
My ResponseData class:
public class ResponseData {
public List<Result> results;
}
I was starting off very basic, just taking a few values from the Json to put into the class and trying to display just the names of the image searches in dynamically created TextViews (based on the search count). I have network permissions already declared in the manifest so I don't think it's a network problem. Any help would be appreciated!
You should put all your code that depends on asynctask in onPostExecute.
#Override
protected void onPostExecute(ResponseData result) {
final int N = result.results.size();
final TextView[] myTextViews = new TextView[N]; // create an empty array;
for (int i = 0; i < N; i++) {
// create a new textview
final TextView textView = new TextView(MainActivity.this);
textView.setText("Image Name:" + result.results.get(i).titleNoFormatting);
RelativeLayout myLayout = (RelativeLayout) findViewById(R.id.container);
// add the textview to the linearlayout
myLayout.addView(textView);
// save a reference to the textview for later
myTextViews[i] = textView;
}
super.onPostExecute(result);
}
EDIT:
I missed a thing. Wherever was response.results use result.results instead. It was in two lines:
final int N = result.results.size();
and
textView.setText("Image Name:" + result.results.get(i).titleNoFormatting);
If you get null again, maybe it is because name of your class 'ResponseData' and mark in json 'responseData' are not the same (first letter).