I have 2 activities with a separate NavHostFragment which hosts 3 fragments, these 3 fragments are then displayed in my activity's layout ContainerView.
Note: My 2 activities have the same name and use the same layout, the only difference is that they are in different directories and handle slightly different tasks.
Initially, I planned on using all fragments for the app but now, I decided to use only one for the first release, then work on the others later because it was tasking to handle all at once
So I want to safely remove the bottom navigation view and the other two fragments(second & third fragment).
Already, I have initially tried doing it on my own by deleting those fragments and erasing any code related to it but it came up with a lot of errors, so I decided to bring it here to see if anyone could help with the safest possible way that I could remove them so that my first fragment
can continue to function without any issues.
It is a weather app, so I receive current city updates on the first fragment. I was supposed to receive hourly & daily updates on the second & third fragments but I've halted my plan, for now, I want to use only the first fragment.
Here are the principal codes:
Activity\HomeActivity:
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
// Last update time, click sound, search button, search panel.
TextView timeField;
MediaPlayer player;
ImageView Search;
EditText textfield;
// For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
ConstraintLayout constraintLayout;
public static int count = 0;
int[] drawable = new int[]{R.drawable.nyc, R.drawable.lofoten_islands, R.drawable.parque, R.drawable.moraine_lake, R.drawable.eiffel_tower,
R.drawable.whitehaven_beach, R.drawable.london, R.drawable.cape_town, R.drawable.burj_al_arab,R.drawable.atuh_beach};
Timer _t;
private WeatherDataViewModel viewModel;
private AppBarConfiguration appBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// use home activity layout.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Allow activity to make use of the toolbar
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// Hiding default Drawer fragment that has the BottomNavView
navigationView.getMenu().findItem(R.id.main_id).setVisible(false);
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// Trigger action to open & close navigation drawer
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
timeField = findViewById(R.id.textView9);
Search = findViewById(R.id.imageView4);
textfield = findViewById(R.id.textfield);
// find the id's of specific variables.
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
// host 3 fragments along with bottom navigation.
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
// Make hourly & daily tab unusable
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
}
return false;
});
toggle.setToolbarNavigationClickListener(v -> {
// Enable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(true);
navController.navigate(R.id.main_id);
});
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
// remove up button from all these fragments
appBarConfiguration = new AppBarConfiguration.Builder(
R.id.main_id) // remove up button from all these fragments >> Keep up button in R.id.nav_setting, R.id.nav_slideshow
.setOpenableLayout(drawer)
.build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
// navController.addOnDestinationChangedListener((controller, destination, arguments) -> navController.popBackStack(destination.getId(), false));
// navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
// });
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
// Hide/show top search bar
if (destination.getId() == R.id.main_id) {
Search.setVisibility(View.VISIBLE);
textfield.setVisibility(View.VISIBLE);
} else {
Search.setVisibility(View.GONE);
textfield.setVisibility(View.GONE);
}
// Fragments that you want to show the back button
if (destination.getId() == R.id.about_id || destination.getId() == R.id.privacy_policy_id) {
// Disable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(false);
}
});
// For scheduling background image change
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.nyc);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// run on ui thread
runOnUiThread(() -> {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
});
}
}, 5000, 5000);
Search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// make click sound when search button is clicked.
player = MediaPlayer.create(HomeActivity.this, R.raw.click);
player.start();
getWeatherData(textfield.getText().toString().trim());
// make use of some fragment's data
Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
if (currentFragment instanceof FirstFragment) {
FirstFragment firstFragment = (FirstFragment) currentFragment;
firstFragment.getWeatherData(textfield.getText().toString().trim());
} else if (currentFragment instanceof SecondFragment) {
SecondFragment secondFragment = (SecondFragment) currentFragment;
secondFragment.getWeatherData(textfield.getText().toString().trim());
} else if (currentFragment instanceof ThirdFragment) {
ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
thirdFragment.getWeatherData(textfield.getText().toString().trim());
}
}
private void getWeatherData(String name) {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(#NonNull Call<Example> call, #NonNull Response<Example> response) {
try {
assert response.body() != null;
timeField.setVisibility(View.VISIBLE);
timeField.setText("First Updated:" + " " + response.body().getDt());
} catch (Exception e) {
timeField.setVisibility(View.GONE);
timeField.setText("First Updated: Unknown");
Log.e("TAG", "No City found");
Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NotNull Call<Example> call, #NotNull Throwable t) {
t.printStackTrace();
}
});
}
});
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.about_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new About()).commit();
break;
case R.id.privacy_policy_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Privacy_Policy()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
// Open/close drawer animation
}
}
#Override
protected void onPause () {
super.onPause();
if (viewModel.getMediaPlayer() != null)
viewModel.getMediaPlayer().pause();
}
#Override
protected void onResume () {
super.onResume();
if (viewModel.getMediaPlayer() != null) {
viewModel.getMediaPlayer().start();
viewModel.getMediaPlayer().setLooping(true);
}
}
#Override
public boolean onSupportNavigateUp() {
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp(); // navigateUp tries to pop the backstack
}
}
Lightweatherforecast\HomeActivity:
public class HomeActivity extends AppCompatActivity {
private DrawerLayout drawer;
// Last update time, click sound, search button, search panel.
TextView timeField;
MediaPlayer player;
ImageView Search;
ConstraintLayout searchbar;
EditText textfield;
// For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
ConstraintLayout constraintLayout;
public static int count = 0;
int[] drawable = new int[]{R.drawable.nyc, R.drawable.lofoten_islands, R.drawable.parque, R.drawable.moraine_lake, R.drawable.eiffel_tower,
R.drawable.whitehaven_beach, R.drawable.london, R.drawable.cape_town, R.drawable.burj_al_arab, R.drawable.atuh_beach};
Timer _t;
private WeatherDataViewModel viewModel;
private AppBarConfiguration appBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// use home activity layout.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Allow activity to make use of the toolbar
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// host 3 fragments along with bottom navigation.
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
// remove up button from all these fragments
appBarConfiguration = new AppBarConfiguration.Builder(
R.id.main_id) // remove up button from all these fragments >> Keep up button in R.id.nav_setting, R.id.nav_slideshow
.setOpenableLayout(drawer)
.build();
// Hiding default Drawer fragment that has the BottomNavView
navigationView.getMenu().findItem(R.id.main_id).setVisible(false);
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// Trigger action to open & close navigation drawer
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
timeField = findViewById(R.id.textView9);
Search = findViewById(R.id.imageView4);
textfield = findViewById(R.id.textfield);
searchbar = findViewById(R.id.searchbar);
// find the id's of specific variables.
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
toggle.setToolbarNavigationClickListener(v -> {
// Enable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(true);
navController.navigate(R.id.main_id);
});
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
// Hide/show top search bar
if (destination.getId() == R.id.main_id) {
searchbar.setVisibility(View.VISIBLE);
toggle.setHomeAsUpIndicator(R.drawable.nav_back_arrow);
toggle.setDrawerIndicatorEnabled(true); // <<< Add this line of code to enable the burger icon
} else {
searchbar.setVisibility(View.GONE);
}
// Fragments that you want to show the back button
if (destination.getId() == R.id.about_id || destination.getId() == R.id.privacy_policy_id) {
// Disable the functionality of opening the side drawer, when the burger icon is clicked
toggle.setDrawerIndicatorEnabled(false);
}
});
// For scheduling background image change
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.nyc);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// run on ui thread
runOnUiThread(() -> {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
});
}
}, 5000, 5000);
Search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// make click sound when search button is clicked.
player = MediaPlayer.create(HomeActivity.this, R.raw.click);
player.start();
getWeatherData(textfield.getText().toString().trim());
// make use of some fragment's data
Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
if (currentFragment instanceof MainFragment) {
((MainFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}
}
private void getWeatherData(String name) {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(#NonNull Call<Example> call, #NonNull Response<Example> response) {
try {
assert response.body() != null;
} catch (Exception e) {
Log.e("TAG", "No City found");
Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NotNull Call<Example> call, #NotNull Throwable t) {
t.printStackTrace();
}
});
}
});
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
// Open/close drawer animation
}
}
#Override
protected void onPause() {
super.onPause();
if (viewModel.getMediaPlayer() != null)
viewModel.getMediaPlayer().pause();
}
#Override
protected void onResume() {
super.onResume();
if (viewModel.getMediaPlayer() != null) {
viewModel.getMediaPlayer().start();
viewModel.getMediaPlayer().setLooping(true);
}
}
#Override
public boolean onSupportNavigateUp() {
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
// return NavigationUI.navigateUp(navController,drawer);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp(); // navigateUp tries to pop the backstack
}
}
MainFragment(The Navhost fragment):
public class MainFragment extends Fragment {
private NavHostFragment navHostFragment;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//
BottomNavigationView bottomNavigationView = rootView.findViewById(R.id.bottomNavigationView);
navHostFragment = (NavHostFragment) getChildFragmentManager().findFragmentById(R.id.nav_host_fragment_content_bottom_nav_view);
if (navHostFragment != null) {
NavController navController = navHostFragment.getNavController();
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
// Exit the app when back is pressed
requireActivity().finish();
}
});
return rootView;
}
public void getWeatherData(String name) {
Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
if (currentFragment instanceof FirstFragment) {
FirstFragment firstFragment = (FirstFragment) currentFragment;
firstFragment.getWeatherData(name);
} else if (currentFragment instanceof SecondFragment) {
SecondFragment secondFragment = (SecondFragment) currentFragment;
secondFragment.getWeatherData(name);
} else if (currentFragment instanceof ThirdFragment) {
ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
thirdFragment.getWeatherData(name);
}
}
}
Others include:
*FirstFragment
*SecondFragment
*ThirdFragment with their respective layouts
*Navigation and menu layouts.
I will not post them, for now, to reduce complexity if needed please don't
hesitate to ask.
So, the current navigation in summary would be:
HomeActivity
MainFragment
BottomNavigationView navGraph
FirstFragment
SecondFragment
ThirdFragment
Other fragments...
And you need to:
Safely remove the BottomNavigationView
Keep only FirstFragment and Get rid of SecondFragment & ThirdFragment
As the MainFragment only hosts the BottomNavigationView; then you can replace it directly with the FirstFragment; so the navigation would be:
HomeActivity
FirstFragment
Other fragments...
And to do that:
1. In the main navGraph of the HomeActivity:
Replace the MainFragment with FirstFragment (copy the FirstFragment section from the BottomNavigationView navGraph to the main navGraph.
Refactor the id of the FirstFragment to the one associated with the MainFragment, because this id is utilized in HomeActivity (or you can do the other way by refactoring it to the FirstFragment)
2. In HomeActivity, Replace the MainFragment in below snippet with the FirstFragment:
if (currentFragment instanceof MainFragment) {
((MainFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}
So, it'll be:
if (currentFragment instanceof FirstFragment) {
((FirstFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}
This is what appears in the shared code; but you'd replace every single occurrence of MainFragment with FirstFragment, and do any needed refactoring.
Now, you can safely remove the MainFragment will all of its descendants, BottomNavigationView, second & third fragments; and their resources (layouts, menus...), or keep them aside if you're planning to reuse them in the future.
Are you try this for bottom navigation?
android:visibility="gone"
I do the samething before.
navController.addOnDestinationChangedListener { _, destination, _ ->
if(destination.id == R.id.first_fragment) {
// your intro fragment will hide your bottomNavigationView
bottomNavigationView.visibility = View.GONE
} else if (destination.id == R.id.second_fragment){
// your second fragment will show your bottomNavigationView
bottomNavigationView.visibility = View.VISIBLE
}
}
You can hide and show according to the relevant destination.
Related
I have been investigating for like 4 hours about this problem, but I didnt get any help.
On summary, I am trying to navigate between fragments in Android Studio, using Navigation View. I want to go from Home Fragment to Services Fragment.
The first Home Fragment always load, but when I click on Services item, the fragment Services load, but the data from Home always keeps on the fragment too.
This is my code:
HOME FRAGMENT CLASS
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
private PieChart pieChart;
private UserService userService;
private Calendar calendar;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
pieChart = root.findViewById(R.id.pieChart);
userService = UserRepository.getUserService();
getData();
return root;
}
private void getData(){
calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH)+1;
Log.i("INT MONTH", String.valueOf(month));
userService.getHoursPerService(String.valueOf(UserCache.empleado.getId_emp()),String.valueOf(month)).enqueue(new Callback<List<Servicio>>() {
#Override
public void onResponse(Call<List<Servicio>> call, Response<List<Servicio>> response) {
if(response.body().size() == 0){
pieChart.setNoDataText("Sin horas actuales.");
pieChart.setNoDataTextColor(ContextCompat.getColor(getContext(), R.color.colorPrimaryDark));
pieChart.invalidate();
}else{
List<Servicio> list = response.body();
List<PieEntry> pieEntries = new ArrayList<>();
for(int cont=0;cont<list.size();cont++){
pieEntries.add(new PieEntry(list.get(cont).getTotalHoras(), list.get(cont).getLugarServicio()));
}
SimpleDateFormat sdf = new SimpleDateFormat("MMMM");
String actual_month = sdf.format(calendar.getTime());
PieDataSet dataSet = new PieDataSet(pieEntries, getResources().getString(R.string.txt_hours_of)+" "+actual_month);
dataSet.setSliceSpace(3f);
dataSet.setSelectionShift(5f);
dataSet.setColors(ColorTemplate.MATERIAL_COLORS);
PieData data = new PieData(dataSet);
data.setValueTextSize(10f);
data.setValueTextColor(ContextCompat.getColor(getContext(), R.color.colorPrimaryDark));
pieChart.getDescription().setEnabled(true);
pieChart.getDescription().setText(getResources().getString(R.string.txt_hours_of)+" "+actual_month+".");
pieChart.getDescription().setTextSize(12f);
pieChart.getDescription().setTextColor(ContextCompat.getColor(getContext(), R.color.colorPrimaryDark));
pieChart.setExtraOffsets(5, 10, 5, 5);
pieChart.setDragDecelerationFrictionCoef(0.99f);
pieChart.setDrawHoleEnabled(true);
pieChart.setHoleColor(Color.WHITE);
pieChart.setTransparentCircleRadius(61f);
pieChart.animateY(2000, Easing.EaseInOutCubic);
pieChart.setEntryLabelColor(ContextCompat.getColor(getContext(),R.color.colorPrimaryDark));
pieChart.setData(data);
pieChart.invalidate();
}
}
#Override
public void onFailure(Call<List<Servicio>> call, Throwable t) {
}
});
}
}
SERVICES FRAGMENT CLASS
public class ServicesFragment extends Fragment {
private ServicesViewModel servicesViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
servicesViewModel = ViewModelProviders.of(this).get(ServicesViewModel.class);
View root = inflater.inflate(R.layout.fragment_myservices, container, false);
final TextView textView = root.findViewById(R.id.text_gallery);
servicesViewModel.getText().observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
return root;
}
}
MAIN ACTIVITY
public class MainActivityView extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private AppBarConfiguration mAppBarConfiguration;
private NavigationView navigationView;
private ActionBarDrawerToggle toggle;
private TextView userNameNav;
private TextView userEmailNav;
private DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_view);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
/*FloatingActionButton fab = 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();
}
});*/
drawer = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_myservices, R.id.nav_startservice)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
View headerView = navigationView.getHeaderView(0);
navigationView.setNavigationItemSelectedListener(this);
userNameNav = headerView.findViewById(R.id.userNameNav);
userEmailNav = headerView.findViewById(R.id.userEmailNav);
userNameNav.setText(UserCache.empleado.getNombre()+" "+UserCache.empleado.getApellidos());
userEmailNav.setText(UserCache.empleado.getEmail());
navigationView.bringToFront();
}
#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_activity_view, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
#Override
public void onBackPressed() {
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else{
AlertDialog.Builder alerta = new AlertDialog.Builder(this);
alerta.setTitle(getResources().getString(R.string.txt_dialog_exit_app));
alerta.setPositiveButton(getResources().getString(R.string.txt_yes_option), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
alerta.setNegativeButton(getResources().getString(R.string.txt_no_option), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alerta.show();
}
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.nav_home:
getSupportFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment,new HomeFragment()).commit();
case R.id.nav_myservices:
getSupportFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new ServicesFragment()).commit();
//NavHostFragment.findNavController(new ServicesFragment());
break;
case R.id.nav_startservice:
getSupportFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new StartServiceFragment()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
onNavigationItemSelected is where I do the navigation.
I tried everything, changing the ConstraintLayout to Relative, insert the fragments from xml into framelayout...
Also, I am using MVVM.
If more information is needed i can post here then.
PD: Sorry if I posting something wrong, this is my first time here.
SOLUTION: I forgot completly to break the first case onNavigationItemSelected.
I started off with a Navigation drawer activity and I added a recyclerView into the content_main.xml but I have been unable to implement the RecyclerView into the ManiActivity.java file.
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.addDrawerListener(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_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} 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;
}
}
That is what my MainAcitity.java looks like when I haven't only implemented the NavigationView Activity.
public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
MyRecyclerViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// data to populate the RecyclerView with
ArrayList<String> animalNames = new ArrayList<>();
animalNames.add("Horse");
animalNames.add("Cow");
animalNames.add("Camel");
animalNames.add("Sheep");
animalNames.add("Goat");
// set up the RecyclerView
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvAnimals);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(this, animalNames);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
}
#Override
public void onItemClick(View view, int position) {
Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
}
}
And I also need this(the recyclerview) into my MainActivity.java There isn't room for both
This code below is my adapter class and the whole struggle is to add this to the MainActivity.java
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private List<String> mData = Collections.emptyList();
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public MyRecyclerViewAdapter(Context context, List<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
// binds the data to the textview in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView myTextView;
public ViewHolder(View itemView) {
super(itemView);
myTextView = (TextView) itemView.findViewById(R.id.tvAnimalName);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
public String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
You need to implement both NavigationView.OnNavigationItemSelectedListener and MyRecyclerViewAdapter.ItemClickListener interfaces on the MainActivity class. This way you would be able to call the adapter class for the Recycler view.Your code should look like this:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, MyRecyclerViewAdapter.ItemClickListener {
MyRecyclerViewAdapter adapter;
#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.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// data to populate the RecyclerView with
ArrayList<String> animalNames = new ArrayList<>();
animalNames.add("Horse");
animalNames.add("Cow");
animalNames.add("Camel");
animalNames.add("Sheep");
animalNames.add("Goat");
// set up the RecyclerView
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvAnimals);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(this, animalNames);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
}
#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) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} 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;
}
#Override
public void onItemClick(View view, int position) {
Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
}
}
In Java, a class can implement more than one interfaces and a class can only extend from one parent. Implementation of more than one interfaces eliminates multiple inheritance which is not allowed in Java.
For example:
ClassA implements ClassB, ClassC
Your edited code can be found here
Problem seems to be associated with Adapter class. I would like to see your code for adapter.
1. Make sure if count is not equal to zero.
2. Make sure you are inflating a proper view in adapter class.
3. The view you are inflating must have external layout Relative or Linear or Constraint.
public class HomeActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener{
TabLayout tabLayout;
ViewPager viewPager;
NavigationView navigationView;
View navHeaderView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
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) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navHeaderView = navigationView.getHeaderView(0);
viewPager = (ViewPager) findViewById(R.id.viewPagerContainer);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
textViewNavigationName = (TextView)
navHeaderView.findViewById(R.id.textViewNavigationName);
textViewNavigationEmail = (TextView)
navHeaderView.findViewById(R.id.textViewNavigationEmail);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
Fragment_Home objFragment1 = new Fragment_Home();
fragmentTransaction.add(R.id.viewPagerContainer, objFragment1).addToBackStack("backkkkkkkkkkkkk");
fragmentTransaction.commit();
}
}
public class Fragment_Home extends Fragment
{
private static final String ARG_PAGE_KEY = "arg_page";
String nextPageToken;
String prevPageToken;
String pageToken;
int sizeOfPlaylist;
int sizeOfCurrentList;
int firstItemPosition;
MenuItem nextItem;
MenuItem lastItem;
LinearLayout linearLayoutProgress, linearLayoutNoConnection;
Button buttonReload;
RecyclerView recyclerViewVideos;
AllVideosAdapterR adapter;
TextView textViewProgress;
public static Fragment_Home newInstance(int pageNumber) {
Fragment_Home myFragment = new Fragment_Home();
Bundle arguments = new Bundle();
arguments.putInt(ARG_PAGE_KEY, pageNumber);
myFragment.setArguments(arguments);
return myFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
LayoutInflater inflater1 = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater1.inflate(R.layout.fragment_home, container, false);
getActivity().invalidateOptionsMenu();
findControls(view);
gettingList();
buttonReload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gettingList();
}
});
return view;
}
public void findControls(View view)
{
recyclerViewVideos = (RecyclerView)view.findViewById(R.id.recyclerViewVideos);
linearLayoutProgress = (LinearLayout)view. findViewById(R.id.linearLayoutProgress);
textViewProgress = (TextView) view.findViewById(R.id.textViewProgress);
linearLayoutProgress.setVisibility(View.INVISIBLE);
linearLayoutNoConnection = (LinearLayout)view.findViewById(R.id.linearLayoutNoConnection);
linearLayoutNoConnection.setVisibility(View.INVISIBLE);
buttonReload = (Button)view.findViewById(R.id.buttonReload);
}
private boolean isDeviceOnline() {
ConnectivityManager connMgr =
(ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
public void setAdapter(List<Item> listItems) {
recyclerViewVideos.setLayoutManager(new
LinearLayoutManager(getActivity()));
adapter = new AllVideosAdapterR(getActivity(), listItems);
recyclerViewVideos.setAdapter(adapter);
}
public void showProgress(String message) {
textViewProgress.setText(message);
linearLayoutProgress.setVisibility(View.VISIBLE);
}
public void stopProgress() {
linearLayoutProgress.setVisibility(View.INVISIBLE);
}
public void gettingList() {
if (!isDeviceOnline()) {
linearLayoutNoConnection.setVisibility(View.VISIBLE);
} else {
linearLayoutNoConnection.setVisibility(View.INVISIBLE);
}
showProgress("Loading videos..");
Retrofit retrofit = newRetrofit.Builder().baseUrl(BaseUrls.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
WebApis call1 = retrofit.create(WebApis.class);
Call<ListResponse> call = call1.requestList();
call.enqueue(new Callback<ListResponse>() {
#Override
public void onResponse(Call<ListResponse> call, Response<ListResponse> response) {
System.out.println("size....................." + response.body().getItems().size());
setAdapter(response.body().getItems());
sizeOfPlaylist = response.body().getPageInfo().getTotalResults();
try {
nextPageToken = response.body().getNextPageToken();
prevPageToken = response.body().getPrevPageToken();
firstItemPosition = response.body().getItems().get(0).getSnippet().getPosition();
sizeOfCurrentList = response.body().getItems().size();
} catch (Exception e) {
Toast.makeText(getActivity(), "More pages not available", Toast.LENGTH_SHORT).show();
}
stopProgress();
}
#Override
public void onFailure(Call<ListResponse> call, Throwable t) {
stopProgress();
Toast.makeText(getActivity(), "Check your Network connection", Toast.LENGTH_LONG).show();
linearLayoutNoConnection.setVisibility(View.VISIBLE);
}
});
}
public void gettingNextList(String token) {
showProgress("Loading videos..");
Retrofit retrofit = new Retrofit.Builder().baseUrl(BaseUrls.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
WebApis call1 = retrofit.create(WebApis.class);
Call<ListResponse> call = call1.requestNextList(token);
call.enqueue(new Callback<ListResponse>() {
#Override
public void onResponse(Call<ListResponse> call, Response<ListResponse> response) {
System.out.println("size....................." + response.body().getItems().size());
setAdapter(response.body().getItems());
try {
nextPageToken = response.body().getNextPageToken();
prevPageToken = response.body().getPrevPageToken();
firstItemPosition = response.body().getItems().get(0).getSnippet().getPosition();
sizeOfCurrentList = response.body().getItems().size();
} catch (Exception e) {
Toast.makeText(getActivity(), "More pages not available", Toast.LENGTH_SHORT).show();
}
stopProgress();
}
#Override
public void onFailure(Call<ListResponse> call, Throwable t) {
stopProgress();
Toast.makeText(getActivity(), "Network Problem", Toast.LENGTH_LONG).show();
}
});
}
public interface WebApis {
#GET(BaseUrls.GETTING_LIST)
Call<ListResponse> requestList();
#GET(BaseUrls.GETTING_LIST)
Call<ListResponse> requestNextList(#Query("pageToken") String pageToken);
}
}
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
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.
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!