I'm new to this fragment coding in Android stuff so I hope this is a simple one for most to answer.
I have a TextView object, 'next', that, when clicked, does not seem to be responding. I want to do a few things when the TextView text is clicked. First, check the String value in the eventName spinner, then Toast the eventID value and finally start a new fragment for the next part of user interaction.
I have not yet implemented the new fragment or a call to the fragment. I assume the way to call the new fragment is with the following code:
NextFragment nextFrag= new NextFragment();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.Layout_container, nextFrag,"findThisFragment")
.addToBackStack(null)
.commit();
My questions are:
Why is the Toast not being displayed? It seems as though the OnCickListener or the OnClick method isn't triggering the Toast.
Is the code above all that I need to do to call a new fragment and make it active in the current Activity or is there something else that I need to add in the Activity code?
Fragment code:
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link FindEventFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link FindEventFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class FindEventFragment extends Fragment{
public static final String TAG = "FindEventFragment";
private VolleyHelper mInstance;
private ArrayList<String> eventList = new ArrayList<String>();
private JSONArray result;
private Spinner eventNameSpinner;
private TextView eventDate;
private String eventID;
private TextView next;
//TextView errorText;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public FindEventFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment FindEventFragment.
*/
// TODO: Rename and change types and number of parameters
public static FindEventFragment newInstance(String param1, String param2) {
FindEventFragment fragment = new FindEventFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
public void onStart() {
super.onStart();
// Instantiate the RequestQueue from VolleyHelper
mInstance = VolleyHelper.getInstance(getActivity().getApplicationContext());
// API
connectApi();
}
#Override
public void onStop () {
super.onStop();
if (mInstance.getRequestQueue() != null) {
mInstance.getRequestQueue().cancelAll(TAG);
}
}
private void connectApi() {
String url = "http://gblakes.ddns.net/get_events.php";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String ServerResponse) {
JSONObject j = null;
try {
result = new JSONArray(ServerResponse);
eventDetails(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getActivity().getApplicationContext(), "Oops, something went wrong", Toast.LENGTH_LONG).show();
}
});
if (mInstance != null) {
// Add a request to your RequestQueue.
mInstance.addToRequestQueue(stringRequest);
// Start the queue
mInstance.getRequestQueue().start();
}
}
private void eventDetails(JSONArray j) {
eventList.add("Choose an event");
for (int i = 0; i < j.length(); i++) {
try {
JSONObject json = j.getJSONObject(i);
// eventList.add(json.getString("EventName") + json.getString("EventDate"));
eventList.add(json.getString("EventName"));
} catch (JSONException e) {
//e.printStackTrace();
Log.d(TAG, e.toString());
}
}
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, eventList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
eventNameSpinner.setAdapter(dataAdapter);
eventNameSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
//Setting the value to textview for a selected item
eventDate.setText(getEventDate(position));
eventID = (getEventID(position));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
eventDate.setText("test me");
}
});
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Make sure the user has made a valid selection
//errorText.setError("");
if (eventNameSpinner.equals("Choose an event")){
//errorText.setError("");
Toast.makeText(getActivity().getApplicationContext(),"Choose an event first",Toast.LENGTH_LONG);
//errorText.setText("Choose an event first");
} else {
//if an event is selected then open the next fragment
Toast.makeText(getActivity().getApplicationContext(),eventID.toString(),Toast.LENGTH_LONG);
}
}
});
}
private String getEventID(int position) {
String eventID = "";
try {
//Getting object of given index
JSONObject json = result.getJSONObject(position);
//Fetching name from that object
eventID = json.getString("EventID");
} catch (JSONException e) {
e.printStackTrace();
}
//Returning the name
return eventID;
}
private String getEventDate(int position){
String eventDate="";
try {
JSONObject json = result.getJSONObject(position);
eventDate = json.getString("EventDate");
} catch (JSONException e) {
e.printStackTrace();
}
return eventDate;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_find_event,container,false);
eventNameSpinner = (Spinner) v.findViewById(R.id.spinEventPicker);
//eventNameSpinner = new Spinner(getActivity().getApplicationContext());
eventDate = (TextView) v.findViewById(R.id.textEventDate);
next = (TextView) v.findViewById(R.id.link_judgeToEvent);
eventDate.setText("test me");
// errorText = (TextView)eventNameSpinner.getSelectedView();
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(eventID);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(String eventID);
}
}
and the fragment's XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:id="#+id/textEventName">
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/spinEventPicker"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:gravity="center"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textEventDate"
android:layout_marginTop="49dp"
android:layout_below="#+id/spinEventPicker"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:id="#+id/link_judgeToEvent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:layout_below="#+id/textEventDate"
android:gravity="center"
android:text="Next"
android:textAlignment="center"
android:textSize="16dip" />
</RelativeLayout>
Toast will display if you call show(), So you have to change the following line of code like this
Toast.makeText(getActivity().getApplicationContext(),"Choose an event first",Toast.LENGTH_LONG).show();
You can use the following code sample code to launch the fragment from another fragment
Fragment2 fragment2 = new Fragment2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fragment2);
fragmentTransaction.commit();
Related
I am trying to implement a dynamic list update to FragmentStatePagerAdapter. I have a list of few fragments which have radio buttons, edit text, and different other fragments having just a single view.
Now the logic revolves around radio button fragment, so lets suppose you have a list having 10 elements and the list item showing the radio button is 6, and there are 2 options for the user to select on the radio button fragment. If user selects 1st option then 8th item should be shown and 7th should be skipped and if 2nd option is selected then 7th should be shown and then 9th.
I have added a view pager, and have an associated FragmentStatePagerAdapter associated with it. Now I was able to populate the list based on the option but when I refresh list in the adapter, it does not hops from 6th to 8th and still shows 7th.
Can someone help me around it on how can I implement the hopping mechanism on FragmentStatePagerAdapter?
Adapter
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup;
import java.util.List;
public class OrderDetailsAdapter extends FragmentPagerAdapter {
private final Logger log = LoggerFactory.getLogger(OrderDetailsAdapter.class);
private List<IndexedFragments> adapterList;
private FragmentManager fragmentManager;
public OrderDetailsAdapter(FragmentManager fragmentManager, List<IndexedFragments> adapterList) {
super(fragmentManager);
this.fragmentManager = fragmentManager;
this.adapterList = adapterList;
}
#Override
public Fragment getItem(int position) {
final IndexedFragments indexedFragment = adapterList.get(position);
return indexedFragment.getFragment();
}
#Override
public int getCount() {
if (adapterList.isEmpty()) {
return 0;
} else {
return adapterList.size();
}
}
#Override
public int getItemPosition(#NonNull Object object) {
return POSITION_NONE;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
log.debug("Destroying fragment position {}", position);
}
public void updateList(List<IndexedFragments> indexedFragments) {
adapterList.clear();
log.debug("Fragment List OrderDetailsAdapter after clearing {} on {}", adapterList.size(), adapterList);
adapterList.addAll(indexedFragments);
log.debug("Fragment List OrderDetailsAdapter after adding indexed fragments {} on {}", adapterList.size(), adapterList);
notifyDataSetChanged();
}
}
Model Class
import android.support.v4.app.Fragment;
import java.io.Serializable;
public class IndexedFragments implements Serializable {
private final static long serialVersionUID = -304520750038118996L;
private Integer index;
private Fragment fragment;
private boolean isSkippedRequested = false;
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public Fragment getFragment() {
return fragment;
}
public void setFragment(Fragment fragment) {
this.fragment = fragment;
}
public boolean isSkippedRequested() {
return isSkippedRequested;
}
public void setSkippedRequested(boolean skippedRequested) {
isSkippedRequested = skippedRequested;
}
}
FormsActivity
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import javax.inject.Inject;
import dagger.Binds;
import dagger.Module;
import dagger.Subcomponent;
import dagger.android.ActivityKey;
import dagger.android.AndroidInjection;
import dagger.android.AndroidInjector;
import dagger.multibindings.IntoMap;
public class FormsActivity extends AppCompatActivity implements FragmentNavigationListener {
private static String CHECK_BOX = "checkbox";
private static String RADIO_BUTTON = "radio";
private static String TEXT_INPUT = "text";
private static String NUMERIC_INPUT = "numeric";
private static String VIDEO_VIEW = "video";
private static String IMAGE_VIEW = "image";
private final Logger log = LoggerFactory.getLogger(FormsActivity.class);
public LinkedHashMap<String, String> stringLinkedHashMap;
#Inject
protected BaseRetrofit restRequests;
#Inject
protected AppUtils appUtils;
private FormData formData;
private ViewPager viewPager;
private ProgressBar progressBar;
private Button submitButton;
private Toolbar toolbar;
private List<Frmdtl> formDataList;
private List<IndexedFragments> fragmentList;
private Context context;
private OrderDetailsAdapter orderDetailsAdapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forms);
context = this;
Intent intent = getIntent();
if (intent != null) {
formData = (FormData) intent.getSerializableExtra(AppConstants.FORMS_ACTIVITY);
}
restRequests.setContext(this);
initializeViews();
populateFragments(formData);
}
#Override
public void onBackPressed() {
showAlertDialog();
}
private void initializeViews() {
submitButton = findViewById(R.id.submit_button);
toolbar = findViewById(R.id.toolbar_main_activity);
setSupportActionBar(toolbar);
progressBar = findViewById(R.id.progress_bar_layout);
}
private void showAlertDialog() {
Dialog dialog = new AlertDialogFragment().createWarningDialog(context, getString(R.string.warning),
getString(R.string.saved_form_data_lost),
R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int which) {
appUtils.getFormAnswersList().clear();
finish();
}
});
dialog.setCanceledOnTouchOutside(true);
dialog.show();
}
#SuppressLint("ClickableViewAccessibility")
private void populateFragments(FormData formData) {
formDataList = formData.getOrderDetails().getFrmdtl();
fragmentList = new ArrayList<>();
for (Frmdtl frmdtl : formDataList) {
Fragment fragment = null;
if (frmdtl.getFieldType().equalsIgnoreCase(TEXT_INPUT)) {
fragment = createTextFieldFragment(frmdtl, null);
} else if (frmdtl.getFieldType().equalsIgnoreCase(NUMERIC_INPUT)) {
fragment = createTextFieldFragment(frmdtl, NUMERIC_TYPE);
} else if (frmdtl.getFieldType().equalsIgnoreCase(CHECK_BOX)) {
fragment = createCheckBoxFragment(frmdtl);
} else if (frmdtl.getFieldType().equalsIgnoreCase(RADIO_BUTTON)) {
fragment = createRadioButtonFragment(frmdtl);
} else if (frmdtl.getFieldType().equalsIgnoreCase(VIDEO_VIEW)) {
fragment = createVideoViewFragment(frmdtl);
} else if (frmdtl.getFieldType().equalsIgnoreCase(IMAGE_VIEW)) {
fragment = createImageViewFragment(frmdtl);
}
if (fragment != null) {
IndexedFragments indexedFragments = new IndexedFragments();
indexedFragments.setFragment(fragment);
indexedFragments.setIndex(frmdtl.getIndex());
fragmentList.add(indexedFragments);
}
}
viewPager = findViewById(R.id.fragment_view_pager);
orderDetailsAdapter = new OrderDetailsAdapter(getSupportFragmentManager(), fragmentList);
viewPager.setAdapter(orderDetailsAdapter);
viewPager.setOffscreenPageLimit(0);
}
private Fragment createTextFieldFragment(Frmdtl formData, String inputType) {
FormEditTextFragment formEditTextFragment = new FormEditTextFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(FORM_DATA, formData);
bundle.putString(INPUT_TYPE, inputType);
formEditTextFragment.setArguments(bundle);
log.debug("Form Data Id for text {}", formData.getId());
return formEditTextFragment;
}
private Fragment createCheckBoxFragment(Frmdtl formData) {
FormCheckBoxFragment formCheckBoxFragment = new FormCheckBoxFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(FORM_DATA, formData);
formCheckBoxFragment.setArguments(bundle);
log.debug("Form Data Id for check {}", formData.getId());
return formCheckBoxFragment;
}
private Fragment createRadioButtonFragment(Frmdtl frmdtl) {
FormRadioButtonFragment formRadioButtonFragment = new FormRadioButtonFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(FORM_DATA, frmdtl);
bundle.putSerializable(ORDER_DETAILS, formData.getOrderDetails());
formRadioButtonFragment.setArguments(bundle);
log.debug("Form Data Id for radio {}", frmdtl.getId());
return formRadioButtonFragment;
}
private Fragment createVideoViewFragment(Frmdtl formData) {
FormVideoFragment formVideoFragment = new FormVideoFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(FORM_DATA, formData);
formVideoFragment.setArguments(bundle);
log.debug("Form Data Id for video {}", formData.getId());
return formVideoFragment;
}
private Fragment createImageViewFragment(Frmdtl formData) {
FormImageFragment formImageFragment = new FormImageFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(FORM_DATA, formData);
formImageFragment.setArguments(bundle);
log.debug("Form Data Id for image {}", formData.getId());
return formImageFragment;
}
private void navigateBetweenFragments(int navigation, List<String> stringList, Integer currentIndex) {
if (navigation == NEXT_NAVIGATION) {
if (stringList != null && !stringList.isEmpty() && currentIndex != null) {
processLogicBasedFragments(stringList, currentIndex);
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
return;
}
if (viewPager.getCurrentItem() == fragmentList.size() - 1) {
log.debug("FormData list size {}", formDataList.size());
log.debug("Moving to {} form", viewPager.getCurrentItem() + 1);
submitButton.setVisibility(View.VISIBLE);
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progressBar.setVisibility(View.VISIBLE);
attemptFormUpload();
}
});
} else {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
}
}
if (navigation == PREVIOUS_NAVIGATION) {
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
}
}
private void processLogicBasedFragments(List<String> stringList, Integer currentIndex) {
List<IndexedFragments> indexedFragmentsList = new ArrayList<>();
for (int i = 0; i < fragmentList.size(); i++) {
Integer index = fragmentList.get(i).getIndex();
if (index.compareTo(currentIndex) <= 0) {
indexedFragmentsList.add(fragmentList.get(i));
}
}
for (int i = 0; i < fragmentList.size(); i++) {
IndexedFragments indexedFragments = fragmentList.get(i);
if (stringList.contains(String.valueOf(indexedFragments.getIndex()))) {
indexedFragmentsList.add(indexedFragments);
} else if (!stringList.contains(String.valueOf(indexedFragments.getIndex()))
&& fragmentList.get(i).getIndex().compareTo(currentIndex) > 0) {
indexedFragments.setSkippedRequested(true);
indexedFragmentsList.add(indexedFragments);
}
}
fragmentList.clear();
log.debug("Fragment List Forms Activity after clearing {} on {}", fragmentList.size(), fragmentList);
fragmentList.addAll(indexedFragmentsList);
log.debug("Fragment List Forms Activity after adding indexed fragments {} on {}", fragmentList.size(), fragmentList);
orderDetailsAdapter.updateList(indexedFragmentsList);
}
private void attemptFormUpload() {
try {
if (appUtils.isNetworkConnected(context)) {
uploadForm();
} else {
preserveFormDataForFutureUpload();
Toast.makeText(context, R.string.no_connection, Toast.LENGTH_LONG).show();
progressBar.setVisibility(GONE);
finish();
}
} catch (IOException e) {
log.error("Error in attempting to upload form {}", e.fillInStackTrace());
}
}
private void uploadForm() throws UnsupportedEncodingException {
restRequests.uploadForm(formData.getOrderDetails().getId(),
String.valueOf(formData.getOrderDetails().getFormId()),
formData.getOrderDetails().getLatitude(),
formData.getOrderDetails().getLongitude(),
appUtils.getFormAnswersList(), new RestRequestListener() {
#Override
public void onSuccessResponse(String response) {
appUtils.getFormAnswersList().clear();
progressBar.setVisibility(GONE);
finish();
}
#Override
public void onErrorResponse(Throwable t) {
appUtils.getFormAnswersList().clear();
progressBar.setVisibility(GONE);
finish();
}
});
}
private void preserveFormDataForFutureUpload() throws IOException {
OfflineSubmittedOrder offlineSubmittedOrder = new OfflineSubmittedOrder();
List<FormAnswers> formAnswers = new ArrayList<>(appUtils.getFormAnswersList());
offlineSubmittedOrder.setFormAnswersList(formAnswers);
offlineSubmittedOrder.setOrderDetail(formData.getOrderDetails());
appUtils.getFormAnswersList().clear();
appUtils.getOfflineSubmittedOrders().add(offlineSubmittedOrder);
appUtils.writeObject(getApplicationContext(), FORM_ANSWER_LIST_CACHE, appUtils.getOfflineSubmittedOrders());
appUtils.setSubmissionPending(true);
}
#Override
public void onFragmentNavigationTriggered(int navigation, List<String> stringList, Integer currentIndex) {
navigateBetweenFragments(navigation, stringList, currentIndex);
}
#Subcomponent
public interface FormsActivitySubcomponent extends AndroidInjector<FormsActivity> {
#SuppressWarnings({"InnerClassTooDeeplyNested", "ClassNameSameAsAncestorName"})
#Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<FormsActivity> {
}
}
#SuppressWarnings("InterfaceNeverImplemented")
#Module(subcomponents = FormsActivity.FormsActivitySubcomponent.class)
public interface FormsActivityModule {
#Binds
#IntoMap
#ActivityKey(FormsActivity.class)
AndroidInjector.Factory<? extends Activity>
bindFormsActivityInjectorFactory(FormsActivity.FormsActivitySubcomponent.Builder builder);
}
}
I have Recyclerview Fragment it work fine but when i change screen rotation , prograss bar not show any more , i know fragment distory all views , is there any way i can save prograss view obj in onsaveinstancestate or other any way to slove this problem ?
package com.example.ameerhamza6733.expressdaily.UI;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import com.example.ameerhamza6733.expressdaily.MainActivity;
import com.example.ameerhamza6733.expressdaily.R;
import com.example.ameerhamza6733.expressdaily.Utils.Constant;
import com.example.ameerhamza6733.expressdaily.Utils.RssFeed;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
/**
* Demonstrates the use of {#link RecyclerView} with a {#link LinearLayoutManager} and a
* {#link GridLayoutManager}.
*/
public class RecyclerViewFragment extends Fragment implements MainActivity.UpdateUI {
private static final String TAG = "RecyclerViewFragment";
private static final String KEY_LAYOUT_MANAGER = "layoutManager";
private static final int SPAN_COUNT = 2;
protected int indexofp = 0, indexOfPdash = 0;
protected LayoutManagerType mCurrentLayoutManagerType;
protected RecyclerView mRecyclerView;
protected CustomAdapter mAdapter;
protected RecyclerView.LayoutManager mLayoutManager;
protected ArrayList<RssFeed> mDataset = new ArrayList<>();
protected RssFeed rssFeed;
protected Context context;
protected String url = Constant.HOME_URL;
protected ProgressBar progressBar;
protected ImageButton mImageButton;
protected boolean dataSetClrear=false;
protected View view;
#Override
public void onArticleNavigationSeleted(String url) {
this.url = url;
mDataset.clear();
dataSetClrear=true;
Log.i(TAG, "Current URL" + url);
}
private enum LayoutManagerType {
GRID_LAYOUT_MANAGER,
LINEAR_LAYOUT_MANAGER
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialize dataset, this data would usually come from a local content provider or
// remote server.
context = getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.recycler_view_frag, container, false);
rootView.setTag(TAG);
this.view = rootView;
// BEGIN_INCLUDE(initializeRecyclerView)
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.myRecylerView);
progressBar = (ProgressBar) rootView.findViewById(R.id.progressBar);
mImageButton = (ImageButton) rootView.findViewById(R.id.mImageButton);
// LinearLayoutManager is used here, this will layout the elements in a similar fashion
// to the way ListView would layout elements. The RecyclerView.LayoutManager defines how
// elements are laid out.
// mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this).color(Color.RED).sizeResId(R.dimen.divider).marginResId(R.dimen.leftmargin, R.dimen.rightmargin).build());
mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getContext()).build());
mLayoutManager = new LinearLayoutManager(getActivity());
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
} else {
mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER;
}
if (savedInstanceState != null ) {
// Restore saved layout manager type.
// mCurrentLayoutManagerType = (LayoutManagerType) savedInstanceState
// .getSerializable(KEY_LAYOUT_MANAGER);
progressBar.setVisibility(View.VISIBLE);
mDataset = savedInstanceState.getParcelableArrayList(Constant.MY_DATA_SET_PARCE_ABLE_ARRAY_KEY);
mAdapter = new CustomAdapter(mDataset);
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
} else {
if (mDataset.isEmpty()) {
progressBar.setVisibility(View.VISIBLE);
initDataset();
}
}
setRecyclerViewLayoutManager(mCurrentLayoutManagerType);
return rootView;
}
/**
* Set RecyclerView's LayoutManager to the one given.
*
* #param layoutManagerType Type of layout manager to switch to.
*/
public void setRecyclerViewLayoutManager(LayoutManagerType layoutManagerType) {
int scrollPosition = 0;
// If a layout manager has already been set, get current scroll position.
if (mRecyclerView.getLayoutManager() != null) {
scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
}
switch (layoutManagerType) {
case GRID_LAYOUT_MANAGER:
mLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT);
mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER;
break;
case LINEAR_LAYOUT_MANAGER:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
break;
default:
mLayoutManager = new LinearLayoutManager(getActivity());
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
}
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.scrollToPosition(scrollPosition);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save currently selected layout manager.
// Save currently selected layout manager.
// savedInstanceState.putSerializable(KEY_LAYOUT_MANAGER, mCurrentLayoutManagerType);
// savedInstanceState.putSerializable(KEY_LAYOUT_MANAGER, (Serializable) progressBar);
savedInstanceState.putParcelableArrayList(Constant.MY_DATA_SET_PARCE_ABLE_ARRAY_KEY, mDataset);
super.onSaveInstanceState(savedInstanceState);
}
/**
* Generates Strings for RecyclerView's adapter. This data would usually come
* from a local content provider or remote server.
*/
private void initDataset() {
if (mDataset.isEmpty()) {
progressBar.setVisibility(View.VISIBLE);
new LoadRssFeedsItems().execute("");
Log.i(TAG, "" + mDataset.size());
Log.i(TAG, "initDataset");
}
}
public class LoadRssFeedsItems extends AsyncTask<String, Void, Void> {
private String mTitle, mDescription, mLink, mPubDate;
private String mCategory, mImageLn;
private String date, mContent;
private ProgressBar bar;
public void setProgressBar(ProgressBar bar) {
this.bar = bar;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if (progressBar != null) {
progressBar.setVisibility(View.VISIBLE);
}
}
#Override
protected void onProgressUpdate(Void... values) {
progressBar.setProgress(1);
super.onProgressUpdate(values);
}
#Override
protected Void doInBackground(String... params) {
Document rssDocument = null;
try {
rssDocument = Jsoup.connect(url).timeout(6000).ignoreContentType(true).parser(Parser.xmlParser()).get();
Elements mItems = rssDocument.select("item");
RssFeed rssItem;
for (Element element : mItems) {
mTitle = element.select("title").first().text();
mDescription = element.select("description").first().text();
mLink = element.select("link").first().text();
mPubDate = element.select("pubDate").first().text();
mCategory = element.select("category").first().text();
mImageLn = element.select("media|content").attr("url").toString();
date = new SimpleDateFormat("dd-MMM-yyyy").format(new Date());
mContent = element.select("content|encoded").first().text();
mContent = Jsoup.parse(mContent).text();
indexofp = mDescription.indexOf(Constant.P);
indexOfPdash = mDescription.indexOf(Constant.P_DASH);
mDescription = mDescription.substring(indexofp + 3, indexOfPdash);
Log.i(TAG, "Item title: " + (mContent == null ? "N/A" : mContent));
Log.i(TAG, "Item title: " + (mTitle == null ? "N/A" : mTitle));
Log.i(TAG, "Item Description: " + (mDescription == null ? "N/A" : mDescription));
Log.i(TAG, "Item link: " + (mLink == null ? "N/A" : mLink));
Log.i(TAG, "Item data: " + (mImageLn == null ? "N/A" : mImageLn));
Log.i(TAG, "Item data: " + (mPubDate == null ? "N/A" : mPubDate));
Log.i(TAG, "system date: " + (date == null ? "N/A" : date));
rssFeed = new RssFeed(mTitle, mLink, mPubDate, mCategory, mLink, mDescription, mImageLn, context, mContent);
mDataset.add(rssFeed);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
if (mDataset.isEmpty()) try {
// mImageButton.setVisibility(View.VISIBLE);
Snackbar mSnackbar = Snackbar.make(view, "انٹرنیٹ دستیاب نہیں ہے", Snackbar.LENGTH_INDEFINITE)
.setAction("دوبارہ کوشش کریں", new View.OnClickListener() {
#Override
public void onClick(View view) {
// Snackbar.make(getView(), "CheckIn Cancelled", Snackbar.LENGTH_LONG).show();
new LoadRssFeedsItems().execute("");
}
});
mSnackbar.show();
} catch (NullPointerException n) {
n.printStackTrace();
}
else {
progressBar.setVisibility(View.INVISIBLE);
mAdapter = new CustomAdapter(mDataset);
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
}
}
}
here is my xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myRecylerView" />
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_marginTop="40dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/progressBar" />
<FrameLayout
android:id="#+id/mFramLaout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="#drawable/ic_cloud_off_black_24dp"
android:id="#+id/mImageButton"
android:elevation="0dp"
android:visibility="gone"
android:background="#f1f1f1" />
</FrameLayout>
</LinearLayout>
You can use Bundle object to this purpose. In onDestroy() function add that line
#Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt("PROGRESS", progress);
}
When Fragment will be recreated you can get back this value using this code in your public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) function by adding this line:
if(savedInstanceState!=null)
{
progress = savedInstanceState.getInt("PROGRESS");
}
Saving a variable at onSaveInstanceState didn't work for me, since you won't get updates while the Activity is destroyed.
I ended up using a ResultReceiver inside a Fragment that doesn't get destroyed by using setRetainInstance(true).
A good article concerning this problem can be found here: https://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
Also see my answer here: https://stackoverflow.com/a/54334864/6747171
I'm a high school student working for a magazine in South Korea known as Teen 10 Magazine. As an aspiring computer science major, I decided to make an RSS reader app for my magazine in order to showcase my skills for college applications (and also to create an app, which has always been my interest). Basically, I want to format my app to be similar to your typical news app (ex. CNN, BBC, etc).
Category Screen
In a DrawerLayout (as seen in the Category Screen), I decided to make a tab for each different category (such as News, Features, Entertainment, etc), including the Home category, which is where the categories the articles are under don't matter. When users click on each different tab, it gives them a list of articles that are categorized under that category. In order to get this data, I'm parsing the data to get the title (which is displayed in the list) and the link (which is set to an Intent so that users can access the article in the Web when it is clicked)
However, while some of the categories do work (Home, Lifestyle, Fashion), the rest of the categories are stuck in the loading screen for almost an infinite amount of time.
Example of loading category
I'm pretty sure that the codes of the categories that work and the categories that don't are the same (for reference, I copied and pasted and adjusted each different category accordingly, which could also be an issue but I'm not sure), and are getting their data from the appropriate sites.
Is it perhaps there are too many parsers (RssParser does the actual parsing and seven different "RssService"s use the parser to parse the data from each different category) for my app to work with? My app does seem to crash once in a while though...
I will post my codes below:
MainActivity.java:
package com.hfad.teen10magazine;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.app.ActionBarDrawerToggle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ShareActionProvider;
import android.support.v4.widget.DrawerLayout;
public class MainActivity extends Activity {
/* adds the fragment to the activity */
private ShareActionProvider shareActionProvider;
private String[] titles;
private ListView drawerList;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle drawerToggle;
private int currentPosition = 0;
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Code to run when an item in the navigation drawer gets clicked
selectItem(position);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
titles = getResources().getStringArray(R.array.titles);
drawerList = (ListView)findViewById(R.id.drawer);
drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
//Initialize the ListView
drawerList.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1, titles));
drawerList.setOnItemClickListener(new DrawerItemClickListener());
//Display the correct fragment.
if (savedInstanceState != null) {
currentPosition = savedInstanceState.getInt("position");
setActionBarTitle(currentPosition);
} else {
selectItem(0);
}
//Create the ActionBarDrawerToggle
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
R.string.open_drawer, R.string.close_drawer) {
//Called when a drawer has settled in a completely closed state
#Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu();
}
//Called when a drawer has settled in a completely open state.
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu();
}
};
drawerLayout.addDrawerListener(drawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
getFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
public void onBackStackChanged() {
FragmentManager fragMan = getFragmentManager();
Fragment fragment = fragMan.findFragmentByTag("visible_fragment");
if (fragment instanceof TopFragment) {
currentPosition = 0;
}
if (fragment instanceof LifestyleFragment) {
currentPosition = 1;
}
if (fragment instanceof EntFragment) {
currentPosition = 2;
}
if (fragment instanceof NewsFragment) {
currentPosition = 3;
}
if (fragment instanceof FeaturesFragment) {
currentPosition = 4;
}
if (fragment instanceof AcademicsFragment) {
currentPosition = 5;
}
if (fragment instanceof FashionFragment) {
currentPosition = 6;
}
setActionBarTitle(currentPosition);
drawerList.setItemChecked(currentPosition, true);
}
}
);
}
private void selectItem(int position) {
// update the main content by replacing fragments
currentPosition = position;
Fragment fragment;
switch(position) {
case 1:
fragment = new LifestyleFragment();
break;
case 2:
fragment = new EntFragment();
break;
case 3:
fragment = new NewsFragment();
break;
case 4:
fragment = new FeaturesFragment();
break;
case 5:
fragment = new AcademicsFragment();
break;
case 6:
fragment = new FashionFragment();
break;
default:
fragment = new TopFragment();
}
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, fragment, "visible_fragment");
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
//Set the action bar title
setActionBarTitle(position);
//Close the drawer
drawerLayout.closeDrawer(drawerList);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the drawer is open, hide action items related to the content view
boolean drawerOpen = drawerLayout.isDrawerOpen(drawerList);
menu.findItem(R.id.action_share).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("position", currentPosition);
}
private void setActionBarTitle(int position) {
String title="";
titles=getResources().getStringArray(R.array.titles);
if (position == 0){
title = getResources().getString(R.string.app_name);
} else {
title = titles[position];
}
getActionBar().setTitle(title);
}
#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);
MenuItem menuItem = menu.findItem(R.id.action_share);
shareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
setIntent("This is example text");
return super.onCreateOptionsMenu(menu);
}
private void setIntent(String text) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, text);
shareActionProvider.setShareIntent(intent);
}
}
RssItem.java:
package com.hfad.teen10magazine;
public class RssItem {
private final String title;
private final String link;
private final String pubDate;
public RssItem(String title, String link, String pubDate) {
this.title = title;
this.link = link;
this.pubDate = pubDate;
}
public String getTitle() {
return title;
}
public String getLink() {
return link;
}
public String getDate() {
return pubDate;
}
}
RssParser.java:
package com.hfad.teen10magazine;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.util.Xml;
public class RssParser {
// We don't use namespaces
private final String ns = null;
public List<RssItem> parse(InputStream inputStream) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(inputStream, null);
parser.nextTag();
return readFeed(parser);
} finally {
inputStream.close();
}
}
private List<RssItem> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, null, "rss");
String title = null;
String link = null;
String pubDate = null;
List<RssItem> items = new ArrayList<RssItem>();
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("title")) {
title = readTitle(parser);
} else if (name.equals("link")) {
link = readLink(parser);
} else if (name.equals("pubDate")) {
pubDate = readDate(parser);
}
if (title != null && link != null && pubDate != null) {
RssItem item = new RssItem(title, link, pubDate);
items.add(item);
title = null;
link = null;
pubDate = null;
}
}
return items;
}
private String readLink(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "link");
String link = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "link");
return link;
}
private String readTitle(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "title");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "title");
return title;
}
private String readDate(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "pubDate");
String pubDate = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "pubDate");
return pubDate;
}
// For the tags title and link, extract their text values.
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
}
Constants.java:
package com.hfad.teen10magazine;
public class Constants {
public static final String TAG = "Teen10MagazineApp";
}
RssAdapter.java:
package com.hfad.teen10magazine;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class RssAdapter extends BaseAdapter {
/* puts the RSS items in a list */
private final List<RssItem> items;
private final Context context;
public RssAdapter(Context context, List<RssItem> items) {
this.items = items;
this.context = context;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(context, R.layout.rss_item, null);
holder = new ViewHolder();
holder.itemTitle = (TextView) convertView.findViewById(R.id.itemTitle);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.itemTitle.setText(items.get(position).getTitle());
return convertView;
}
static class ViewHolder {
TextView itemTitle;
}
}
Along with the main codes, for the sake of time, I will post the codes of one category that works (the fragment it is placed in and the RssService used to get it) and the codes of one that doesn't work. If you need more information or codes, please contact me and I will be happy to provide information:
LifeStyleFragment.java (Works):
package com.hfad.teen10magazine;
import android.app.Fragment;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.util.List;
public class LifestyleFragment extends Fragment implements AdapterView.OnItemClickListener {
private ProgressBar progressBar;
private ListView listView;
private View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view == null) {
view = inflater.inflate(R.layout.fragment_layout, container, false);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
listView = (ListView) view.findViewById(R.id.listView);
listView.setOnItemClickListener(this);
startService();
} else {
// If we are returning from a configuration change:
// "view" is still attached to the previous view hierarchy
// so we need to remove it and re-attach it to the current one
ViewGroup parent = (ViewGroup) view.getParent();
parent.removeView(view);
}
return view;
}
private void startService() {
Intent intent = new Intent(getActivity(), RssService_Lifestyle.class);
intent.putExtra(RssService_Lifestyle.RECEIVER, resultReceiver);
getActivity().startService(intent);
}
private final ResultReceiver resultReceiver = new ResultReceiver(new Handler()) {
#SuppressWarnings("unchecked")
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
List<RssItem> items = (List<RssItem>) resultData.getSerializable(RssService_Lifestyle.ITEMS);
if (items != null) {
RssAdapter adapter = new RssAdapter(getActivity(), items);
listView.setAdapter(adapter);
} else {
Toast.makeText(getActivity(), "An error occurred while downloading the rss feed.",
Toast.LENGTH_LONG).show();
}
progressBar.setVisibility(View.GONE);
listView.setVisibility(View.VISIBLE);
};
};
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
RssAdapter adapter = (RssAdapter) parent.getAdapter();
RssItem item = (RssItem) adapter.getItem(position);
Uri uri = Uri.parse(item.getLink());
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
RssService_Lifestyle.java:
package com.hfad.teen10magazine;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.List;
import org.xmlpull.v1.XmlPullParserException;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;
public class RssService_Lifestyle extends IntentService {
/* parse the rss feed on lifestyle and send the list of items to LifestyleFragment */
private static final String RSS_LINK = "http://www.teen10mag.com/category/lifestyle/feed/";
public static final String ITEMS = "items";
public static final String RECEIVER = "receiver";
public RssService_Lifestyle() {
super("RssService_Lifestyle");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(Constants.TAG, "Service started");
List<RssItem> rssItems = null;
try {
RssParser parser = new RssParser();
rssItems = parser.parse(getInputStream(RSS_LINK));
} catch (XmlPullParserException | IOException e) {
Log.w(e.getMessage(), e);
}
Bundle bundle = new Bundle();
bundle.putSerializable(ITEMS, (Serializable) rssItems);
ResultReceiver receiver = intent.getParcelableExtra(RECEIVER);
receiver.send(0, bundle);
}
public InputStream getInputStream(String link) {
try {
URL url = new URL(link);
return url.openConnection().getInputStream();
} catch (IOException e) {
Log.w(Constants.TAG, "Exception while retrieving the input stream", e);
return null;
}
}
}
AcademicsFragment.java (Doesn't work):
package com.hfad.teen10magazine;
import java.util.List;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;
public class AcademicsFragment extends Fragment implements AdapterView.OnItemClickListener {
private ProgressBar progressBar;
private ListView listView;
private View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view == null) {
view = inflater.inflate(R.layout.fragment_layout, container, false);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
listView = (ListView) view.findViewById(R.id.listView);
listView.setOnItemClickListener(this);
startService();
} else {
// If we are returning from a configuration change:
// "view" is still attached to the previous view hierarchy
// so we need to remove it and re-attach it to the current one
ViewGroup parent = (ViewGroup) view.getParent();
parent.removeView(view);
}
return view;
}
private void startService() {
Intent intent = new Intent(getActivity(), RssService_Academics.class);
intent.putExtra(RssService_Academics.RECEIVER, resultReceiver);
getActivity().startService(intent);
}
private final ResultReceiver resultReceiver = new ResultReceiver(new Handler()) {
#SuppressWarnings("unchecked")
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
List<RssItem> items = (List<RssItem>) resultData.getSerializable(RssService_Academics.ITEMS);
if (items != null) {
RssAdapter adapter = new RssAdapter(getActivity(), items);
listView.setAdapter(adapter);
} else {
Toast.makeText(getActivity(), "An error occurred while downloading the rss feed.",
Toast.LENGTH_LONG).show();
}
progressBar.setVisibility(View.GONE);
listView.setVisibility(View.VISIBLE);
}
};
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
RssAdapter adapter = (RssAdapter) parent.getAdapter();
RssItem item = (RssItem) adapter.getItem(position);
Uri uri = Uri.parse(item.getLink());
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
RssService_Academics.java:
package com.hfad.teen10magazine;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.List;
public class RssService_Academics extends IntentService {
/* parse the rss feed on academics and send the list of items to AcademicsFragment */
private static final String RSS_LINK = "http://www.teen10mag.com/category/academics/feed/";
public static final String ITEMS = "items";
public static final String RECEIVER = "receiver";
public RssService_Academics() {
super("RssService_Academics");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(Constants.TAG, "Service started");
List<RssItem> rssItems = null;
try {
RssParser parser = new RssParser();
rssItems = parser.parse(getInputStream(RSS_LINK));
} catch (XmlPullParserException | IOException e) {
Log.w(e.getMessage(), e);
}
Bundle bundle = new Bundle();
bundle.putSerializable(ITEMS, (Serializable) rssItems);
ResultReceiver receiver = intent.getParcelableExtra(RECEIVER);
receiver.send(0, bundle);
}
public InputStream getInputStream(String link) {
try {
URL url = new URL(link);
return url.openConnection().getInputStream();
} catch (IOException e) {
Log.w(Constants.TAG, "Exception while retrieving the input stream", e);
return null;
}
}
}
This is my first question, so I tried to be as detailed as possible. If my explanations were unreasonably lengthy, I do apologize. This is also my first time coding something this extensive, so forgive me if I seem to make amateur mistakes...
Thank you in advance for all of your help!!
[EDIT]
When I click on the category that doesn't work, the logcat turns up like this:
09-21 19:29:59.237 1541-1866/system_process W/ActivityManager: Unable to start service Intent { cmp=com.hfad.teen10magazine/.RssService_News (has extras) } U=0: not found
09-21 19:30:13.209 2808-2808/com.hfad.teen10magazine I/Choreographer: Skipped 31 frames! The application may be doing too much work on its main thread.
09-21 19:30:21.122 2808-2814/com.hfad.teen10magazine W/art: Suspending all threads took: 13.025ms`
I need to get fragment context inside toast message,
I tried getActivity() and getActivity().getApplicationContext()
and HomeFragment.class and HomeFragment.this, and just this.
I also tried making a global variable that gets the context and passed it in the toast, but it doesn't work Nothing has worked. This is my fragment class
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonObjectRequest;
import net.cairobus.app.activities.ActivityMain;
import net.cairobus.app.app.AppController;
import net.cairobus.app.materialtest.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class HomeFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
private String urlCitiesObj = "url";
private static String TAG = HomeFragment.class.getSimpleName();
private TextView txtResponse;
private String jsonResponse;
//private Context globalContext = null;
private Context globalContext = getActivity().getApplicationContext();
public static HomeFragment newInstance(String param1, String param2) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public HomeFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_home, container, false);
makeJsonArrayRequest();
txtResponse = (TextView) layout.findViewById(R.id.txtResponse);
return layout;
}
private Activity mActivity;
#Override
public void onAttach(Activity activity) {
}
private void makeJsonArrayRequest() {
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
urlCitiesObj, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
try {
JSONArray jsonArray = response.getJSONArray("GetCitiesResult");
for (int i = 0; i < jsonArray .length(); i++) {
JSONObject jSONObject = jsonArray .getJSONObject(i);
String cityID = jSONObject .getString("CityID");
String cityName = jSONObject .getString("CityName");
jsonResponse += "CityID: " + cityID + "\n\n";
jsonResponse += "CityName: " + cityName + "\n\n";
txtResponse.setText(jsonResponse);
}
if( isAdded()){
getActivity().getApplicationContext()
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(mActivity, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
// hide the progress dialog
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
/**
* Return the Activity this fragment is currently associated with.
*/
final public Activity getActivity() {
return mActivity;
}
You must use getActivity() after onAttach(Activity activity) lifecycle method callbacked
Whenever you do anything on the UI, you have to take care that you're doing it from the UI thread.
Change:
Toast.makeText("This is where I need context", "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
to:
getActivity().runOnUIThread(new Runnable() {
#Override
public void run() {
Toast.makeText("This is where I need context", "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
and the same modification for txtResponse.setText(jsonResponse);
Save a reference to the Activty in onAttatch() and use that:
private Activity mActivity;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
getActivity() will return null if the Fragment is not associated with an Activity (yet).
For the same reason the following lines do not work.
private Context globalContext = getActivity().getApplicationContext();
Because at this point the Fragment is not associated to an Activity .
Addition:
If you take a look at the source code of the fragment:
public void onAttach(Activity activity) {
mCalled = true;
}
final public FragmentActivity getActivity() {
return mActivity;
}
Note that mActivity is not assigned onAttach()
Alternative solutions:
checking:
if( getActivity() == null){
// not assigent to an Activity
}
this also works pretty well:
isAdded()
Return true if the fragment is currently added to its activity.
if( isAdded()){
getActivity() // will not return null
}
Addition to the cannot resolve constructor problem:
Try to change:
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
urlCitiesObj, null, new Response.Listener<JSONObject>() {
to
JSONObject obj = null;
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
urlCitiesObj, obj, new Response.Listener<JSONObject>() {
or
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
urlCitiesObj, (String)null, new Response.Listener<JSONObject>() {
We have code that creates a list view with detailed view upon click. There is a wrapper class called drink content containing a drink object and a static code segment that makes a call to an asyncTask that calls our web service. We need to build the URL based on data from another activity but I don't understand the way in which the object is created. We can't seem to replace the general DrinkContent references in the list and detail fragments with a single reference to an instantiated instance of DrinkContent. We wanted to use the instantiated instance of drink content so we could write a constructor that would take in URL parameters generated during another activity. We can pass the URL data to the fragments, but when a constructor was written multiple instances of Drink content were being created and our web service request didn't work. We are storing the parameters in another activities shared preferences and passing them to the new activity.
Code for DrinkListActivity:
package com.cs4720.drinkengine_android;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
public class DrinkListActivity extends FragmentActivity
implements DrinkListFragment.Callbacks {
private boolean mTwoPane;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_list);
if (findViewById(R.id.drink_detail_container) != null) {
mTwoPane = true;
((DrinkListFragment) getSupportFragmentManager()
.findFragmentById(R.id.drink_list))
.setActivateOnItemClick(true);
}
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(DrinkListActivity.this, LeaderboardActivity.class);
startActivity(i);
}
});
}
public void onItemSelected(String id) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(DrinkDetailFragment.ARG_ITEM_ID, id);
DrinkDetailFragment fragment = new DrinkDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.drink_detail_container, fragment)
.commit();
} else {
Intent detailIntent = new Intent(this, DrinkDetailActivity.class);
detailIntent.putExtra(DrinkDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
}
}
code for DrinkListFragment
package com.cs4720.drinkengine_android;
import com.cs4720.drinkengine_android.dummy.DrinkContent;
import com.cs4720.drinkengine_android.dummy.DrinkContent.GetDrinksTask;
import android.R;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class DrinkListFragment extends ListFragment {
private static final String STATE_ACTIVATED_POSITION = "activated_position";
private Callbacks mCallbacks = sDummyCallbacks;
private int mActivatedPosition = ListView.INVALID_POSITION;
public interface Callbacks {
public void onItemSelected(String id);
}
private static Callbacks sDummyCallbacks = new Callbacks() {
public void onItemSelected(String id) {
}
};
public DrinkListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<DrinkContent.Drink>(getActivity(),
R.layout.simple_list_item_activated_1,
R.id.text1,
DrinkContent.ITEMS));
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState != null && savedInstanceState
.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = sDummyCallbacks;
}
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
mCallbacks.onItemSelected(DrinkContent.ITEMS.get(position).name);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
public void setActivateOnItemClick(boolean activateOnItemClick) {
getListView().setChoiceMode(activateOnItemClick
? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
public void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
}
code for DrinkDetailActivity
package com.cs4720.drinkengine_android;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
public class DrinkDetailActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_detail);
getActionBar().setDisplayHomeAsUpEnabled(true);
if (savedInstanceState == null) {
Bundle arguments = new Bundle();
arguments.putString(DrinkDetailFragment.ARG_ITEM_ID,
getIntent().getStringExtra(DrinkDetailFragment.ARG_ITEM_ID));
DrinkDetailFragment fragment = new DrinkDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.drink_detail_container, fragment)
.commit();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
NavUtils.navigateUpTo(this, new Intent(this, DrinkListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
code for drinkDetailFragment
package com.cs4720.drinkengine_android;
import com.cs4720.drinkengine_android.dummy.DrinkContent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DrinkDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
DrinkContent.Drink mItem;
public DrinkDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
mItem = DrinkContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_drink_detail, container, false);
if (mItem != null) {
String miss="";
if(mItem.missing == 0){
miss = "You can make this Drink!";
}
else{
miss = "Missing "+ mItem.missing + " ingredients";
}
StringBuilder sb = new StringBuilder();
sb.append("Name: " + mItem.name
+ "\n" + miss
+ "\nDecription: " + mItem.description
+ "\nCalories: " + mItem.calories
+ "\nStrength: " + mItem.strength
+ "\nIngredients: \n");
for(int i = 0; i < mItem.units.size(); i++)
sb.append(mItem.units.get(i) + " " + mItem.ingredients.get(i) + "\n");
((TextView) rootView.findViewById(R.id.drink_detail)).setText(sb.toString());
}
return rootView;
}
}
code for DrinkContent
package com.cs4720.drinkengine_android.dummy;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.util.Log;
public class DrinkContent {
public static class Drink {
public String name;
public int missing;
public String description;
public int calories;
public int strength;
public List<String> units;
public List<String> ingredients;
public Drink(String name) {
super();
this.name = name;
}
#Override
public String toString() {
return name;
}
}
public static String url = "http://drinkengine.appspot.com/view";
public static List<Drink> ITEMS = new ArrayList<Drink>();
public static Map<String, Drink> ITEM_MAP = new HashMap<String, Drink>();
static{
new GetDrinksTask().execute(url);
}
private static void addItem(Drink item) {
ITEMS.add(item);
ITEM_MAP.put(item.name, item);
}
public static String getJSONfromURL(String url) {
// initialize
InputStream is = null;
String result = "";
// http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("DrinkEngine", "Error in http connection " + e.toString());
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("DrinkEngine", "Error converting result " + e.toString());
}
return result;
}
// The definition of our task class
public static class GetDrinksTask extends AsyncTask<String, Integer, String> {
SharedPreferences prefs;
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
String url = params[0];
ArrayList<Drink> lcs = new ArrayList<Drink>();
try {
String webJSON = getJSONfromURL(url);
JSONArray drinks = new JSONArray(webJSON);
for (int i = 0; i < drinks.length(); i++) {
JSONObject jo = drinks.getJSONObject(i);
Drink current = new Drink(jo.getString("name"));
current.missing = Integer.parseInt(jo.getString("missing"));
current.description = jo.getString("description");
current.calories = Integer.parseInt(jo.getString("calories"));
current.strength = Integer.parseInt(jo.getString("strength"));
JSONArray units = jo.getJSONArray("units");
current.units = new ArrayList<String>();
for(int j = 0; j < units.length(); j++){
current.units.add(units.getString(j));
}
JSONArray ingredients = jo.getJSONArray("ingredients");
current.ingredients = new ArrayList<String>();
for(int j = 0; j < ingredients.length(); j++){
current.ingredients.add(ingredients.getString(j));
}
addItem(current);
}
} catch (Exception e) {
Log.e("DrinkEngine", "JSONPARSE:" + e.toString());
}
return "Done!";
}
#Override
protected void onProgressUpdate(Integer... ints) {
}
#Override
protected void onPostExecute(String result) {
// tells the adapter that the underlying data has changed and it
// needs to update the view
}
}
}
So now that youve seen the code the question might make more sense. We need to access our URL params from within drink content. But those parameters changed based on user input from another activity. We store those params in the other activities shared prefs and them pass them the DrinkListActivity and attempted to write a constructor that would take in the params and build the url properly. This did not work when we replaced the generalized DrinkContent and DrinkContent.LIST references with our instance we created. So basically how do we get the info inside of this class from our shared prefs?
SharedPreferences are shared across application level and not only activity level. It can actually be shared between applications if it is set to public. You should go read the documentation here and here as it explains this quite well.