When my app starts up, it replaces layout with fragment, that needs AsyncTask to load correctly. When I load this fragment from navigation drawer, everything works fine, but wen it loads on app startup, AsyncTask doesn't execute. How can i fix this?
MainActivity:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Fragment fragment = null;
Class fragmentClass = null;
fragmentClass = NewsFragment.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frameLayoutForFragments, fragment);
fragmentTransaction.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.getMenu().getItem(0).setChecked(true);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
//Wybory elementów w navigationdrawer
Fragment fragment = null;
Class fragmentClass = null;
int id = item.getItemId();
if (id == R.id.nav_news) {
fragmentClass = NewsFragment.class;
} else if (id == R.id.nav_map) {
fragmentClass = MapFragment.class;
} else if (id == R.id.nav_buildings) {
fragmentClass = BuildingsFragment.class;
} else if (id == R.id.nav_manage) {
fragmentClass = MapFragment.class;
} else if (id == R.id.nav_info) {
fragmentClass = AppInfoFragment.class;
} else if (id == R.id.nav_bugreport) {
fragmentClass = ContactFragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frameLayoutForFragments, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Fragment that loads on startup:
public class NewsFragment extends Fragment {
public static ArrayList <ParsedWebData> list = new ArrayList<ParsedWebData>();
public NewsFragment() {
// Required empty public constructor
}
public static NewsFragment newInstance(Context context) {
NewsFragment fragment = new NewsFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Start AsyncTask w momencie ładowania fragmentu
AsyncXMLParser parser = new AsyncXMLParser();
parser.execute();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_news, container, false);
ListView listView = (ListView) view.findViewById(R.id.listViewNews);
CustomListViewAdapter customListViewAdapter = new CustomListViewAdapter(getContext(), R.id.listViewNews, list);
listView.setAdapter(customListViewAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
ParsedWebData singleData = list.get(position);
String url = singleData.getUrl();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
}
});
return view;
}
}
AsyncTask:
public class AsyncXMLParser extends AsyncTask <Void, Integer, ArrayList<ParsedWebData>> {
#Override
protected void onPreExecute() {
}
#Override
protected ArrayList<ParsedWebData> doInBackground(Void... params) {
ArrayList<ParsedWebData> list = new ArrayList<ParsedWebData>();
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
// We will get the XML from an input stream
InputStream input = new URL("linkhere").openStream();
xpp.setInput(input, "UTF_8");
int eventType = xpp.getEventType();
String text = null;
ParsedWebData data = new ParsedWebData();
while (eventType != XmlPullParser.END_DOCUMENT) {
String tagname = xpp.getName();
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagname.equalsIgnoreCase("item")) {
data = new ParsedWebData();
}
break;
case XmlPullParser.TEXT:
text = xpp.getText();
break;
case XmlPullParser.END_TAG:
if (tagname.equalsIgnoreCase("item")) {
// add employee object to list
list.add(data);
} else if (tagname.equalsIgnoreCase("title")) {
data.title = text;
} else if (tagname.equalsIgnoreCase("link")) {
data.url = text;
} else if (tagname.equalsIgnoreCase("description")) {
text = Jsoup.parse(text).text();
data.description = text;
}
break;
default:
break;
}
eventType = xpp.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
NewsFragment.list = list;
return list;
}
#Override
protected void onPostExecute(ArrayList <ParsedWebData> result) {
}
}
I tried to find the reason myself, and tried to execute AsyncTask manually in MainActivity, but it didn't help. Any ideas what's wrong?
What's wrong is, that the AsyncTask (thread) finishes after your OnCreateView runs, so you don't see your data.
What you could do, is move the line of code NewsFragment.list = list; from doInBackground(), to onPostExecute(), and call adapter.notifyDataSetChanged() after that. But the issue is that in your design you have no access to listView adapter in AsyncTask
In addition, having the list as a static variable in the Fragment, so that you can access it from the AsyncTask is very bad programming design.
You should remove the static list variable, and should redesign your AsyncTask, that you pass the listView to the constructor (you will have to move it from onCreate to onCreateView), and assign the listView to a member in the AsyncTask. Then in onPostExecute set the adapter (not in onCreateView)
public class AsyncXMLParser extends AsyncTask <Void, Integer, ArrayList<ParsedWebData>> {
CustomListViewAdapter _adapter;
Public AsyncXMLParser(CustomListViewAdapter adapter) {
_adapter = adapter;
}
...
#Override
protected void onPostExecute(ArrayList <ParsedWebData> result) {
CustomListViewAdapter customListViewAdapter = new CustomListViewAdapter(getContext(), R.id.listViewNews, result);
listView.setAdapter(customListViewAdapter);
// Or, depending on design
_adapter.notifyDataSetChanged();
}
}
This way, the list is not static variable (you can remove code from the fragment), and the listView is filled only after the AsyncTask is finished. If you later need access to the actual list data, you can get it from the Adapter.
I couldn't find the reason to why Asynctask isnt being executed but depending on how much background work you want to do, you might not want to use
Asynctask. Asynctask should only be used to do operations that take a small amount of time(at most seconds) since its lifetime is tied to the lifetime of a ui compoment. The issue here could very well be that you're killing the asynctask because its connected to the ui.
I would recommend you to use an intentservice. They are really easy to use and can run as long as you like in the background. Since u can't seem to find the issue with Asynctask in this case you would probably save time by using intentservices instead. https://developer.android.com/reference/android/app/IntentService.html
Related
I'm trying to open file.txt from my raw folder through a fragment.
here is my code on KonsumerFragment.java
public class KonsumerFragment extends Fragment implements View.OnClickListener{
public KonsumerFragment() {
// Required empty public constructor
}
float marginValue;
Spinner spinnerProduct;
Spinner spinnerType;
EditText pengajuan;
EditText tenor;
TextView tvAngsuran;
String[] arrayMargin;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_konsumer, container, false);
//Define Variables
spinnerProduct = (Spinner) v.findViewById(R.id.spinnerProduct) ;
spinnerType = (Spinner) v.findViewById(R.id.spinnerType);
pengajuan = (EditText) v.findViewById(R.id.etPengajuan);
tenor = (EditText) v.findViewById(R.id.etTenor);
// Inflate the layout for this fragment
Button hitung = (Button) v.findViewById(R.id.btnHitung);
hitung.setOnClickListener(this);
return v;
}
#Override
public void onClick(View view) {
try {
switch (view.getId()){
case R.id.btnHitung :
//simulate();
readMargin();
break;
}
} catch (Exception e){
e.getCause();
e.printStackTrace();
}
}
public void readMargin() throws FileNotFoundException {
try {
InputStream in = getContext().getResources().openRawResource(R.raw.margingriyafix);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();
String result = "";
while(line !=null){
result += line + "\n";
}
arrayMargin = result.split("\\n");
for (int i=0 ; i<arrayMargin.length ; i++){
System.out.println(arrayMargin[i]);
}
System.out.println(arrayMargin);
} catch (Exception e){
System.out.println(e);
e.getCause();
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
KonsumerFragment konsFragment = new KonsumerFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frameLayout, konsFragment);
transaction.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_konsumer) {
KonsumerFragment konsFragment = new KonsumerFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frameLayout, konsFragment);
transaction.commit();
} else if (id == R.id.nav_produktif) {
ProduktifFragment prodFragment = new ProduktifFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frameLayout, prodFragment);
transaction.commit();
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
the part of the reading file has been in the right way. I tested it running on MainAcivity directly. but it won't run on Fragment. it has been successfully running on an Activity, I believe that the problem comes from the InputStream, but anyway I've tried doing like
getActivity().getResources().openRawResource(R.raw.margingriyafix);
and also
getContext().getResources().openRawResource(R.raw.margingriyafix);
still not working.
please anyone help me.
This is kind of hard to explain so I took screenshots of my problem.
So this is my MainActivity.java
I open the navigation drawer and click on Milestones which will bring me to Milestones.java
Here I am at Milestones.java fragment...
working fine for now...
Just how I want it to look.
But when we leave Milestones and go anywhere else and come back it will be messed up. So I will go to Kick Counter.
Here I am in my KickCounter.java fragment
Open navigation drawer and going back to Milestones...
So right now I have fragment Months0Through6 open with Milestones fragment. Some times Months0Through6 and Month12Plus fragments does not show up right away after coming back some times it does. What is always messed up at this point is the Months6Through12 fragment will never display again unless you restart the app. Also swapping between the three fragments is laggy after coming back but never on first view.
Here it is. Where did it go?
youtube video: https://www.youtube.com/watch?v=6yMYcluvqbs
Get Source Here: https://github.com/delaroy/RecyclerViewFragment
I got my code from this youtube video which is almost exactly identical but his MainActivity (which I made into my Milestones fragment) is an activity whereas I used a fragment so I was thinking that might have something to do with my problem.
Milestones.java
public class Milestones extends Fragment {
// 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 Milestones() {
// 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 Milestones.
*/
// TODO: Rename and change types and number of parameters
public static Milestones newInstance(String param1, String param2) {
Milestones fragment = new Milestones();
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);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_milestones, container, false);
Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
//dont know if this will work
PagerAdapter pagerAdapter = new PagerAdapter(getFragmentManager(), getContext());
viewPager.setAdapter(pagerAdapter);
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
for(int i = 0; i < tabLayout.getTabCount(); i++){
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
// Inflate the layout for this fragment
return rootView;
}
// not boiler plate
#Override
public void onResume() {
super.onResume();
}
// probably just adding extra menu dont need it
/*#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
*/
//not boilerplate
#Override
public boolean onOptionsItemSelected(MenuItem item){
int id = item.getItemId();
if(id == R.id.action_settings){
return true;
}
return super.onOptionsItemSelected(item);
}
//not boilerplate
class PagerAdapter extends FragmentPagerAdapter {
String tabTitles[] = new String[]{"0-6 Months", "6-12 Months", "12+ Months"};
Context context;
public PagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return tabTitles.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new Months0Through6();
case 1:
return new Months6Through12();
case 2:
return new Months12Plus();
}
return null;
}
#Override
public CharSequence getPageTitle(int position){
return tabTitles[position];
}
public View getTabView(int position){
View tab = LayoutInflater.from(getContext()).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) tab.findViewById(R.id.custom_text);
tv.setText(tabTitles[position]);
return tab;
}
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#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;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
MilestonesAdapter.java
public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.MyViewHolder> {
private String[] mDataset;
public static class MyViewHolder extends RecyclerView.ViewHolder{
public CardView mCardView;
public TextView mTextView;
public MyViewHolder(View v){
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextView = (TextView) v.findViewById(R.id.tv_text);
}
}
public MilestonesAdapter(String[] myDataset){
mDataset = myDataset;
}
#Override
public MilestonesAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_item, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position){
holder.mTextView.setText(mDataset[position]);
}
#Override
public int getItemCount() { return mDataset.length; }
Just posting Months0Through6.java because the other two are exactly the same just different strings.
public class Months0Through6 extends android.support.v4.app.Fragment {
public Months0Through6() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_blank, container, false);
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv_recycler_view);
rv.setHasFixedSize(true);
MilestonesAdapter adapter = new MilestonesAdapter(new String[]{"Month 0 stuff", "Example Two", "Example Three", "Example Four", "Example Five" , "Example Six" , "Example Seven"});
rv.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
return rootView;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity
implements KickCounter.OnFragmentInteractionListener, MommyMetrics.OnFragmentInteractionListener, Milestones.OnFragmentInteractionListener, NavigationView.OnNavigationItemSelectedListener {
Intent shareIntent;
String sharetext = "Hey check out mommy-info here at http://www.mommy-info.com";
private WebView myWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Connects to www.mommy-info.com
myWebView = (WebView)findViewById(R.id.webView_ID);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("http://www.mommy-info.com");
myWebView.setWebViewClient(new WebViewClient());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
//back button in navigation drawer logic
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
//back button in webView logic
else if(myWebView.canGoBack()){
myWebView.goBack();
}
else if(getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
}
else{
super.onBackPressed();
}
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.kick_counter_ID) {
KickCounter kickCounter = new KickCounter();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.full_screen_ID, kickCounter).addToBackStack(null).commit();
} else if (id == R.id.nav_mommy_metrics) {
MommyMetrics mommyMetrics = new MommyMetrics();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.full_screen_ID, mommyMetrics).addToBackStack(null).commit();
} else if (id == R.id.nav_milestones) {
Milestones milestones = new Milestones();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.full_screen_ID, milestones).addToBackStack(null).commit();
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "my app");
shareIntent.putExtra(Intent.EXTRA_TEXT, sharetext);
startActivity(Intent.createChooser(shareIntent, "share via"));
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
In Fragments you need to use getChildFragmentManager(), You are using same Fragment manager in the fragments as in Activity. Hope this will help
I am getting the error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
when trying to set the text of a textView within a fragment (in the method changeText)
Here is my fragment code
public class MainFragment extends Fragment {
String date;
TextView infoText2;
public MainFragment() {
// Required empty public constructor
}
public Boolean daily;
//instantiate variables
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootview = inflater.inflate(R.layout.fragment_main, container, false);
infoText2 = (TextView) rootview.findViewById(R.id.infoText2);
//TODO THIS COULD POSSIBLY BE A PROBLEM TOO
//calls setdate function
startup(rootview);
btnClick(rootview);
return rootview;
}
public void startup(View v) {
date = new SimpleDateFormat("dd/MM/yyyy").format(new Date());
//gets the current date
TextView textView = (TextView) v.findViewById(R.id.infoText);
textView.setText(date);
//finds and replaces text in textView
SeekBar seekBar = (SeekBar) v.findViewById(R.id.seekBar2);
seekBar.setProgress(5);
seekBar.setMax(10);
//sets the seekbar progress
//BEGIN CHECKING IF USER HAS ADDED ENTRY
//TODO ADD IF ENTRY NOT COMPLETED STATEMENT
}
public void changeText(String mText) {
//TODO FIX THIS PROBLEM
infoText2.setText(mText);
//runs getTheData method
}
public void btnClick(View v) {
Button clickButton = (Button) v.findViewById(R.id.btnRate);
clickButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainFragment.this.getActivity(), "Rating successful", Toast.LENGTH_SHORT).show();
//conformation toast
SeekBar seekBar = (SeekBar) MainFragment.this.getActivity().findViewById(R.id.seekBar2);
seekBar.setEnabled(false);
Button btnRate = (Button) MainFragment.this.getActivity().findViewById(R.id.btnRate);
btnRate.setEnabled(false);
//disable seekbar and button
daily = true;
//marks rating complete for the day
//TODO reset complete back to false the next day
int value = seekBar.getProgress();
TextView ratingDisplay = (TextView) MainFragment.this.getActivity().findViewById(R.id.ratingText);
ratingDisplay.setText("Rating: " + Integer.toString(value) + " out of 10");
//sets the rating display to the value of the seekbar
((MainActivity) getActivity()).writeText(date, Integer.toString(value));
//Runs writeText method
((MainActivity) getActivity()).getTheData();
}
});
and also here is the code from my MainActivity
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
NavigationView navigationView = null;
Toolbar toolbar = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//sets the initial fragment
MainFragment fragment = new MainFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
//sets up the navigation drawer
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
/*public void rateOnClickListener(){
Button btnNavigator = (Button)findViewById(R.id.btnRate);
btnNavigator.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MainFragment fragment = new MainFragment();
MainFragment.rate(v);
Toast.makeText(MainActivity.this, "yes", Toast.LENGTH_LONG);
}
});
}*/
//if the user presses the back button when the navdrawer is open
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
MainFragment fragment = new MainFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else if (id == R.id.nav_gallery) {
SecondFragment fragment = new SecondFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
public void writeText(String timestamp, String rating) {
String my_results = rating + ", " + timestamp + "\n";
// String my results contains the date/time and the my_total score
String file_name = "fresh_3";
try {
FileOutputStream fileOutputStream = openFileOutput(file_name, MODE_APPEND | MODE_PRIVATE);
fileOutputStream.write(my_results.getBytes());
fileOutputStream.close();
Toast.makeText(getApplicationContext(), my_results + " success", Toast.LENGTH_LONG).show();
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
//saves values to file
}
public void getTheData() {
try {
String Message;
String myData;
int i = 0;
FileInputStream fileInputStream = openFileInput("fresh_3");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
while ((Message = bufferedReader.readLine()) != null) {
stringBuilder.append(Message + "\n");
i++; //counter for the array to sort the data
}
//put data in a string with lines
fileInputStream.close();
myData = stringBuilder.toString(); // old successful method to output - need to count the lines
//instantiate the array
String mylines[] = new String[i]; //assigning number of lines to new array as Java cannot make a indeterminate array
mylines = myData.split("\\n");
Arrays.sort(mylines, Collections.reverseOrder()); //sort the array in order of first character - reverse order - descending
//remove the dodgy brackets and print the sorted data
MainFragment mainFragment = new MainFragment();
mainFragment.changeText(Arrays.toString(mylines).replaceAll("\\[|\\]", "")); //write the sorted data using regex (regular expression)
//infoText2.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), "Number of records " + i, Toast.LENGTH_LONG).show(); //shows line number
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
}
}
I have tried all sorts of things to fix this including getActivity() in front of the findViewById and also rootview.. I have re-arranged them in different positions but nothing has worked.
It appears that everything apart from the .setText is working but I would very much appreciate it if somebody could tell me why it refuses to cooperate.
The fragment is not attached to the activity when onCreateView runs. To make sure it works, call the needed functions in the OnResume() of the fragment.
For example:
gridview_left = (GridView)getView().findViewById(R.id.gridview_left);
Make sure that TextView with #+id/infoText2 exists in fragment_main layout file.
Try shifting the btnClick(rootview) call inside the onActivityCreated()...
I think the fragment is not yet attached to the activity
MainFragment mainFragment = new MainFragment();
mainFragment.changeText(Arrays.toString(mylines).replaceAll("\\[|\\]", ""));
None of the fragment lifecycle methods such as onCreateView() have been run when you're invoking a method on the fragment here. You'd need to wait for your fragment transaction to be executed.
A better idea would be to use the arguments Bundle to pass parameters to your fragment, and read the arguments in the fragment itself in a lifecycle method.
in my main activity I initialized a class with a method which download data from my server.
I want to show a Progress Dialog until the download. But it doesn't show the Progress Dialog.
My Main Activity:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
setFragmentManager(new MainActivityFragment());
Updater updater = new Updater(this,(ViewGroup) findViewById(R.id.fragment));
updater.check();
}
public void setFragmentManager(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
#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();
switch (id){
case R.id.action_settings:
return true;
case R.id.medi_calc_item:
setFragmentManager(new MediCalcFragment());
default:
return super.onOptionsItemSelected(item);
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
switch (id){
case R.id.nav_start:
setFragmentManager(new MainActivityFragment());
break;
case R.id.nav_medis:
setFragmentManager(new MediAbcFragment());
break;
case R.id.nav_bos:
setFragmentManager(new BosAbcFragment());
break;
default:
break;
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
My Class:
public class Updater {
private Context context;
private ViewGroup viewGroup;
private VersionsDAO versionsDAO;
private MediDAO mediDAO;
private RegioDAO regioDAO;
private HashMap<String,Integer> onlineVersions;
private HashMap<String,Integer> versions;
private ProgressDialog progressDialog;
public Updater(Context context, ViewGroup viewGroup) {
this.context = context;
this.versionsDAO = new VersionsDAO(context);
this.mediDAO = new MediDAO(context);
this.viewGroup = viewGroup;
this.onlineVersions = new HashMap<>();
this.regioDAO = new RegioDAO(context);
this.progressDialog = new ProgressDialog(context);
}
public void check(){
progressDialog.setMessage(context.getString(R.string.update_cities));
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setIndeterminate(true);
progressDialog.show();
RequestQueue queue = Volley.newRequestQueue(this.context);
String url ="http://resper.de/resperApi.php?cmd=deStadt";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jArray = new JSONArray(response);
for(int i = 0; i < jArray.length(); i++){
JSONObject jObject = jArray.getJSONObject(i);
regioDAO.insertDeStadt(jObject.getInt("id"), jObject.getString("name"), jObject.getInt("bl"), jObject.getInt("rb"), jObject.getInt("kreis"), jObject.getInt("lk"));
}
versionsDAO.updateVersion("deStadt", onlineVersions.get("deStadt"));
progressDialog.cancel();
}catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
serverNotAvailable();
}
});
queue.add(stringRequest);
progressDialog.cancel();
}
}
Remove progressDialog.cancel(); from last line. That is after queue.add(stringRequest); and try again.
Hello everyone I have a question on rotating fragments and restoring them after detaching them. Currently I have three fragments: Fragment_Data, Fragment_Log, and Fragment_Control. My problem is if I rotate Fragment_Data, then detach and add Fragment_Log, then detach Fragment_Log and attempt to attach Fragment Data it fails to reattach. If I keep the device vertical and repeat the same steps the fragments don't have any issues reattaching. I try to detach, add, and attach the fragments in my PanelManager method.
What exactly is going one during the lifecycle of the Fragment_Data that causes issues when trying to reattach?
MainActivty.java
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, FragmentControl.ButtonSetListener{
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentControlTransction = fragmentManager.beginTransaction();
FragmentTransaction fragmentDataTransaction = fragmentManager.beginTransaction();
FragmentControl fragmentControl = new FragmentControl();
FragmentData fragmentData = new FragmentData();
FragmentLog fragmentLog = new FragmentLog();
FragmentGraph fragmentGraph = new FragmentGraph();
//Create Fragment Manager
FragmentManager panelManager = getFragmentManager();
//Boolean values for panels
boolean data_panel = true; //True because it is the first panel created in the View; id = 1
boolean log_panel = false; //id = 2
boolean graph_panel = false; //id = 3
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if(savedInstanceState != null){
return;
}
//Generate Fragment_Data and Fragment_Control Panels
//These are the first two panels introduced into the app
fragmentControlTransction.add(R.id.fragment_control_panel, fragmentControl, "control");
fragmentControlTransction.commit();
fragmentDataTransaction.add(R.id.fragment_data_panel, fragmentData, "data");
fragmentDataTransaction.commit();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.data_log) {
PanelManager(2);
} else if (id == R.id.data_graph) {
PanelManager(3);
} else if (id == R.id.nav_share) {
PanelManager(1);
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private void PanelManager(int panel_id){
if(panel_id == 1){
//detach any panel attached to the fragment_data_panel
panelManager.beginTransaction().detach(getFragmentManager().findFragmentById(R.id.fragment_data_panel)).commit();
//Switch to data panel since it already exists
panelManager.beginTransaction().attach(fragmentData).commit();
} else if(panel_id == 2){
//detach any panel attached to the fragment_data_panel
panelManager.beginTransaction().detach(getFragmentManager().findFragmentById(R.id.fragment_data_panel)).commit();
//Switch to log panel
if(log_panel == false){
//If log panel is false, create log_panel for the first time
log_panel = true;
panelManager.beginTransaction().add(R.id.fragment_data_panel, fragmentLog).commit();
} else {
//Log_panel exists, so just attach fragment back
panelManager.beginTransaction().attach(fragmentLog).commit();
}
} else if(panel_id == 3){
//detach any panel attached to the fragment_data_panel
panelManager.beginTransaction().detach(getFragmentManager().findFragmentById(R.id.fragment_data_panel)).commit();
//Switch to graph panel
if(graph_panel == false){
//If log panel is false, create graph_panel for the first time
graph_panel = true;
panelManager.beginTransaction().add(R.id.fragment_data_panel, fragmentGraph).commit();
} else {
//Log_panel exists, so just attach fragment back
panelManager.beginTransaction().attach(fragmentGraph).commit();
}
}
}
//Call updateList method in FragmentLog to update ListView
#Override
public void app_log_update(String data, int icon) {
FragmentLog fragmentLog = (FragmentLog)getFragmentManager().findFragmentById(R.id.fragment_data_panel);
fragmentLog.updateList(data, icon);
}
}
FragmentData.java
public class FragmentData extends Fragment implements View.OnClickListener{
public EditText message_text;
public TextView display_message;
public Button button;
public String return_message = null;
boolean has_text_entered = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
return_message = savedInstanceState.getCharSequence("savedText").toString();
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_data, container, false);
button = (Button)view.findViewById(R.id.set_text_button);
button.setOnClickListener(this);
display_message = (TextView) view.findViewById(R.id.display_message);
display_message.setText("This is a temp statement");
if(return_message != null){
display_message = (TextView) view.findViewById(R.id.display_message);
display_message.setText(return_message);
}
return view;
}
#Override
public void onClick(View v) {
has_text_entered = true;
message_text = (EditText)getActivity().findViewById(R.id.text_message);
String message = message_text.getText().toString();
display_message = (TextView)getActivity().findViewById(R.id.display_message);
display_message.setText(message);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
TextView text = (TextView)getActivity().findViewById(R.id.display_message);
CharSequence userText = text.getText();
if(userText != null){outState.putCharSequence("savedText", userText);}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
}
Thank you for the help everyone!