I am creating a simple application which will have a bottom navigation view.
This will take the user between various categories. This has been setup with Fragments and a case system
I then want buttons on these category pages which take you to other pages with the navigation at bottom of each of the pages.
When I put my button code I used on the previous version of this application it fails saying
error: cannot find symbol method findViewById(int)
After some reading I can see this doesnt work with fragments but I cant find anything clear or easy to understand as to how to make these work.
In short, i would like the nav panel to stay constant on any page i load not just the category pages i have listed in the panel.
Any of the letter pages and other links from buttons need to open in the panel above the nav bar but i have no clue how to implement this.
Any help would be ... helpful. I have spent about 12 hours trying various things with no avail.
Code to handle navigation fragments:
package breed.sheep.british.com.britishsheepbreeds;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import breed.sheep.british.com.britishsheepbreeds.fragment.BreedsFragment;
import breed.sheep.british.com.britishsheepbreeds.fragment.ColoursFragment;
import breed.sheep.british.com.britishsheepbreeds.fragment.DefaultFragment;
import breed.sheep.british.com.britishsheepbreeds.fragment.TerminologyFragment;
import breed.sheep.british.com.britishsheepbreeds.fragment.TypeFragment;
import breed.sheep.british.com.britishsheepbreeds.helper.BottomNavigationBehavior;
public class MainActivity extends AppCompatActivity {
private ActionBar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = getSupportActionBar();
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
BottomNavigationBehavior.disableShiftMode(navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
// attaching bottom sheet behaviour - hide / show on scroll
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) navigation.getLayoutParams();
layoutParams.setBehavior(new BottomNavigationBehavior());
// load the default fragment
toolbar.setTitle("British Sheep Breeds");
loadFragment(new DefaultFragment());
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment;
switch (item.getItemId()) {
case R.id.home:
toolbar.setTitle("British Sheep Breeds");
fragment = new DefaultFragment();
loadFragment(fragment);
return true;
case R.id.breeds:
toolbar.setTitle("Breeds A-Z");
fragment = new BreedsFragment();
loadFragment(fragment);
return true;
case R.id.colour:
toolbar.setTitle("Colours");
fragment = new ColoursFragment();
loadFragment(fragment);
return true;
case R.id.type:
toolbar.setTitle("Type ");
fragment = new TypeFragment();
loadFragment(fragment);
return true;
case R.id.term:
toolbar.setTitle("Terminology ");
fragment = new TerminologyFragment();
loadFragment(fragment);
return true;
}
return false;
}
};
/**
* loading fragment into FrameLayout
*
* #param fragment
*/
private void loadFragment(Fragment fragment) {
// load fragment
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack(null);
transaction.commit();
} }
Fragment page
package breed.sheep.british.com.britishsheepbreeds.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import breed.sheep.british.com.britishsheepbreeds.R;
public class DefaultFragment extends Fragment {
public DefaultFragment() {
// Required empty public constructor
}
public static DefaultFragment newInstance(String param1, String param2) {
DefaultFragment fragment = new DefaultFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
previous button code
Button balwen = (Button) findViewById(R.id.balwen);
balwen.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), balwen.class);
startActivityForResult(myIntent, 0);
}
});
Button balwenLeft, balwenRight;
FragmentManager fragmentManager;
Fragment fragment;
public Timeline() {
// Required empty public constructor
}
public static Timeline newInstance(String param1, String param2) {
Timeline fragment = new Timeline();
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);
}
fragmentManager = this.getActivity().getSupportFragmentManager();
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
final LinearLayout l = (LinearLayout) inflater.inflate(R.layout.fragment_colours, container, false);
fragment = new FirstPageOnBreedFragment();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.channelactivitycontainer, fragment).commit();
balwenLeft = (Button) l.findViewById(R.id.btnLeft);
balwenLeft.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
fragment = new AnotherFragmentWithInBreedFrag();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.frame_container, fragment).commit();
}
});
balwenRight = (Button) l.findViewById(R.id.btnRight);
balwenRight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
fragment = new AnotherFragmentWithInBreedFrag();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.frame_container, fragment).commit();
}
});
return l;
So this looks like what you might want to do, what's actually happening is that from each fragment as a category, you will create the custom navigations buttons on the layouts and when calling it from the fragment,
Don't forget that you will need to inflate the layouts of the fragment like i did, the parent layout of the fragment layout is LinearLayout in my case, so if you're using Relating layout or Coor... just change them respectively, and back to the navigations, what's happening is that I'm hard coding it but you can replace it with your switch case function that's actually simpler, so if you're on BreedsFragment, You will have two Buttons that will help you navigate between the pages in BreedFrag... In general we're just replacing whatever is present in frame_container just like the bottom nav does, same thing happens when you click the buttons but in this case you'r still on the same page breedFrag, and note that i'm assuming the those pages are also fragements. I hope you understand, else if you can share your code on gitHub I can help contribute to it.
Related
The fragments are a part of the bottom navigation bar, so far so good on the navigation part. But when i try to pass data from fragment1 to fragment2 the app is crashing. Also I am using the example given by google at this following link
When I use the following code android studio gives me deprecated warning!
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
So I am using CONTEXT instead of ACTIVITY below is my code that crashes :
MainActivity
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.br.tron.bottombar.RadioFragment;
import com.br.tron.bottombar.StreamFragment;
import com.br.tron.bottombar.InfoFragment;
public class MainActivity extends AppCompatActivity implements RadioFragment.OnNameSetListener {
BottomNavigationView bottomNavigationView;
private Fragment fragment;
private FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
fragment = new RadioFragment();
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.main_container, fragment).commit();
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationBar);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener(){
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_button_one:
fragment = new RadioFragment();
break;
case R.id.nav_button_two:
fragment = new StreamFragment();
break;
case R.id.nav_button_three:
fragment = new InfoFragment();
break;
}
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_container, fragment).commit();
return true;
}
});
}
public void performStreamClick(){
View view = bottomNavigationView.findViewById(R.id.nav_button_two);
view.performClick();
}
#Override
public void setUrl(String url) {
StreamFragment frag=(StreamFragment) getSupportFragmentManager().findFragmentByTag("frag");
frag.getUrl(url);
}
}
RadioFragment(Fragment1 where the data exist)
import android.app.Activity;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class RadioFragment extends Fragment implements Button.OnClickListener {
Button buttonman;
View rootView;
String url;
Activity a;
OnNameSetListener onNameSetListener;
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof Activity) {
a = (Activity) context;
try{
onNameSetListener=(OnNameSetListener) context;
}
catch (Exception e){}
}
}
public RadioFragment(){
};
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_player, container, false);
buttonman = (Button)rootView.findViewById(R.id.buttonman);
buttonman.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v) {
/*Fragment fragment = new StreamFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();*/
url="www.idontknow.com";
onNameSetListener.setUrl(url);
((MainActivity)a).performStreamClick();
}
public interface OnNameSetListener
{
public void setUrl(String url);
}
}
StreamFragment(fragment2 where I want to send the data -from fragment1)
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class StreamFragment extends Fragment {
TextView textViewStream;
public StreamFragment(){};
#Override
public View onCreateView(final LayoutInflater inflater,final ViewGroup container,final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_stream, container, false);
}
public void getUrl(String url)
{
textViewStream.setText(url);
}
}
LOGCAT
01-06 20:10:23.023 3744-3744/com.br.tron.bottombar E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.br.tron.bottombar, PID: 3744
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.br.tron.bottombar.StreamFragment.getUrl(java.lang.String)' on a null object reference
at com.br.tron.bottombar.MainActivity.setUrl(MainActivity.java:64)
at com.br.tron.bottombar.RadioFragment.onClick(RadioFragment.java:61)
at android.view.View.performClick(View.java:5201)
at android.view.View$PerformClick.run(View.java:21209)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
01-06 20:10:24.663 3744-3744/? I/Process: Sending signal. PID: 3744 SIG: 9
You never register the frag tag you later search for.
In your MainActivity modify:
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.main_container, fragment, "frag").commit();
...
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_container, fragment, "frag").commit();
...
In addition to that within your StreamFragment class you never set the TextViewStream variable after you inflate your layout.
#Override
public View onCreateView(final LayoutInflater inflater,final ViewGroup container,final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_stream, container, false);
textViewStream = (TextView) view.findViewById(R.id.ID_GOES_HERE);
return view;
}
Edit: Further Errors
You're getting a ClassCastException because you're not checking to see whether the fragment you get in MainActivity.setUrl is a StreamFragment. And it makes sense that it's failing because you register the frag tag for all three types of custom Fragments. Here's a further solution:
fragment = new RadioFragment();
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.main_container, fragment, "radio_fragment").commit();
...
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
String tag = "";
case R.id.nav_button_one:
fragment = new RadioFragment();
tag = "radio_fragment";
break;
case R.id.nav_button_two:
fragment = new StreamFragment();
tag = "stream_fragment";
break;
case R.id.nav_button_three:
fragment = new InfoFragment();
tag = "info_fragment";
break;
}
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_container, fragment, tag).commit();
return true;
}
Make the appropriate change in the Tag string in setUrl:
StreamFragment frag=(StreamFragment) getSupportFragmentManager().findFragmentByTag("stream_fragment");
if (frag != null) frag.getUrl(url);
Both of the current answers key in on your crash problem. I expect that will take care of your primary question. #asadmshah seems to have taken care of your next problem. Make sure to up vote his answer & accept it.
Regarding the warning from using Google's example code, here is what AS will currently give you if you tell it to create a new fragment.
#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");
}
}
The point of this is to make sure that the Activity you're attaching to implements the interface you've defined in your fragment.
And on the subject of the interface, all fragment to activity comms should be done through it. It would be better to find a way to call performStreamClick() through the interface as well. (I just realized I made this same mistake on an app I started several months ago but am just finishing up now :).
Lastly, just an FYI, you can get the attached activity of a fragment with getActivity().
EDIT:
1st, it might help to see your current code. I'm going to assume you have what Asad has put in his answer, more or less. Also, what is the expected behavior? I believe that you make a selection in RadioFragment then replace it with StreamFragment. That is, both fragments take the whole nav bar, they don't exist at the same time. If this is wrong, let me know.
If you're still calling setUrl() and performStreamClick() in the same order as before, you're getting null because you've never created a fragment by that name. You can't find a fragment you haven't already created.
Without actually setting this up to test it myself, I believe what you need to do would be to save the url in a global variable in setUrl(), then in your click listener, pass that to the StreamFragment when you create it.
See the "Deliver a Message to a Fragment" section of the link you've sited for doing that
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
(obviously, handling your url string instead of the int in the example)
Also, it's not a bad idea to handle null when searching for a fragment that should exist already
StreamFragment frag=(StreamFragment) getSupportFragmentManager().findFragmentByTag("stream_frag");
if(frag == null) {
final FragmentTransaction transaction = fragmentManager.beginTransaction();
StreamFragment fragment = new StreamFragment();
transaction.replace(R.id.main_container, fragment, "stream_frag").commit();
}
You should initialize your textViewStream in the StreamFragment fragment.
Please suggest me how implement Swipe left or right in my app? Is page viewer or gesture can be used. I get content for text view from string array when item clicked. I am new to app development.
My MainActivity xml
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener
{
private ActionBarDrawerToggle actionBarDrawerToggle;
private DrawerLayout drawerLayout;
private ListView navList;
private FragmentManager fragmentManager;
boolean nightmode=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout)findViewById(R.id.drawerlayout);
navList = (ListView)findViewById(R.id.navlist);
String[] versionName = getResources().getStringArray(R.array.version_names);
navList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, versionName);
navList.setAdapter(adapter);
navList.setOnItemClickListener(this);
actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,R.string.opendrawer,R.string.closedrawer);
drawerLayout.setDrawerListener(actionBarDrawerToggle);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
fragmentManager = getSupportFragmentManager();
OnSelectionChanged(0);
}
public void OnSelectionChanged(int position) {
DescriptionFragment descriptionFragment = (DescriptionFragment) getFragmentManager()
.findFragmentById(R.id.description_fragment);
if (descriptionFragment != null){
// If description is available, we are in two pane layout
// so we call the method in DescriptionFragment to update its content
descriptionFragment.setDescription(position);
} else {
DescriptionFragment newDesriptionFragment = new DescriptionFragment();
Bundle args = new Bundle();
args.putInt(DescriptionFragment.KEY_POSITION,position);
newDesriptionFragment.setArguments(args);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the backStack so the User can navigate back
fragmentTransaction.replace(R.id.fragment_container,newDesriptionFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
actionBarDrawerToggle.syncState();
}
#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) {
TextView textElement = (TextView) findViewById(R.id.version_description);
FrameLayout mainLayout = (FrameLayout) findViewById(R.id.fragment_container);
if(nightmode) textElement.setTextColor(Color.WHITE);
switch(item.getItemId()){
case R.id.action_settings:
if (nightmode) {
mainLayout.setBackgroundResource(R.color.white);
textElement.setTextColor(Color.BLACK);
nightmode=false;
}else {
mainLayout.setBackgroundResource(R.color.background_color);
textElement.setTextColor(Color.WHITE);
nightmode=true;
}
break;
case android.R.id.home:
if (drawerLayout.isDrawerOpen(navList)){
drawerLayout.closeDrawer(navList);
}else{
drawerLayout.openDrawer(navList);
}
break;
case R.id.action_share:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
OnSelectionChanged(position);
drawerLayout.closeDrawer(navList);
}
}
My DescriptionFragment
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by sathi on 16-01-2016.
*/
public class DescriptionFragment extends Fragment {
final static String KEY_POSITION = "position";
int mCurrentPosition = -1;
String[] mVersionDescriptions;
TextView mVersionDescriptionTextView;
public DescriptionFragment(){
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mVersionDescriptions = getResources().getStringArray(R.array.version_descriptions);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/* DescriptionFragment descriptionFragment = new DescriptionFragment();
Object fromFragment = null;
Object toFragment=null;
descriptionFragment.addFragment(Fragment fromFragment, Fragment toFragment);*/
// If the Activity is recreated, the savedInstanceStare Bundle isn't empty
// we restore the previous version name selection set by the Bundle.
// This is necessary when in two pane layout
if (savedInstanceState != null) {
mCurrentPosition = savedInstanceState.getInt(KEY_POSITION);
}
// FragmentTransaction fragmentTransaction = null;
// fragmentTransaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
View view = inflater.inflate(R.layout.fragment_description, container, false);
mVersionDescriptionTextView = (TextView) view.findViewById(R.id.version_description);
return view;
/* DescriptionFragment fragment1 = new DescriptionFragment();
(getSupportFragmentManager().beginTransaction().add(R.id.description_fragment, fragment1)
.add(R.id.description_fragment, fragment1).commit()){
}*/
}
public void addFragment(Fragment fromFragment, Fragment toFragment) {
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.fragment_container,toFragment, toFragment.getClass().getName());
transaction.hide(fromFragment);
transaction.addToBackStack(toFragment.getClass().getName());
transaction.commit();
}
public void replaceFragment(Fragment fromFragment, Fragment toFragment) {
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_container,toFragment, toFragment.getClass().getName());
transaction.hide(fromFragment);
transaction.addToBackStack(toFragment.getClass().getName());
transaction.commit();
}
private FragmentManager getSupportFragmentManager() {
return null;
}
#Override
public void onStart() {
super.onStart();
// During the startup, we check if there are any arguments passed to the fragment.
// onStart() is a good place to do this because the layout has already been
// applied to the fragment at this point so we can safely call the method below
// that sets the description text
Bundle args = getArguments();
if (args != null){
// Set description based on argument passed in
setDescription(args.getInt(KEY_POSITION));
} else if(mCurrentPosition != -1){
// Set description based on savedInstanceState defined during onCreateView()
setDescription(mCurrentPosition);
}
}
public void setDescription(int descriptionIndex){
mVersionDescriptionTextView.setText(mVersionDescriptions[descriptionIndex]);
mCurrentPosition = descriptionIndex;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save the current description selection in case we need to recreate the fragment
outState.putInt(KEY_POSITION,mCurrentPosition);
}
}
I didn't understand if that actually what you trying to do but as i understood if you want the TextView moves automatically in one line to show the rest of it make this:
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true" />
and in code after defining it's view make this:
textView.setChecked(true);
I am adding a tab view or (ViewPager) to my Fragment in an App I am working on.
I want to put the tab view inside the Contact Fragment
I have a Navigation Drawer that opens, and you see list of options...
Home
Services
Contact
Everything you click goes to a fragment
Then in that fragment loads the .XML file, with a corresponding class to program everything inside the .XML file.
I was following an online tutorial [CLICK HERE][3]
Obviously it was over 2 years ago. Android Code has changed since then. I started with a few more errors then what I have now.
I am experiencing an issue with getSupportFragmentManager(), and getActionBar() really confused at this point, all imports are there. It won't recognize those two. Obviously that makes me think well something is missing, but I am not sure what needs to put to allow the compiler to see those needed methods.
I still get Null when the ViewPager setAdapter is set.
All I am trying to accomplish is a tab view, with two tabs for Contact, and Social Media. If I could get a simplistic understanding of what is required for tabs to work properly.
I have already searched questions and they don't exactly touch on my specific issue, and so I am asking for help. Any help is definitely appreciated.
FragmentContact
package com.megliosolutions.bitsnbytes.Fragments;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.megliosolutions.bitsnbytes.MainActivity;
import com.megliosolutions.bitsnbytes.R;
import com.megliosolutions.bitsnbytes.ViewPagerClasses.TabsPagerAdapter;
/**
* Created by Jarvis on 6/21/15.
*/
public class FragmentContact extends Fragment {
private ViewPager viewPager;
TabsPagerAdapter mAdapter;
private ActionBar actionBar;
private String[] tabs = {"Contact", "Social Media"};
public static FragmentContact newInstance(){
FragmentContact fragment = new FragmentContact();
return fragment;
}
public FragmentContact(){};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_contact, container, false);
LoadTabs(rootView);
return rootView;
}
private void LoadTabs(View rootView) {
FragmentManager fragmentManager = getSupportFragmentManager();
// Initilization
viewPager = (ViewPager) rootView.findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(fragmentManager);
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener((ActionBar.TabListener) this));
}
}
#Override
public void onAttach(FragmentActivity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(5);
}
}
TabsPagerAdapter
package com.megliosolutions.bitsnbytes.ViewPagerClasses;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.View;
/**
* Created by Jarvis on 6/28/15.
*/
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Contact fragment activity
return new ContactFragment();
case 1:
// Social Media fragment activity
return new SocialMediaFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
}
MAINACTIVITY
package com.megliosolutions.bitsnbytes;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.megliosolutions.bitsnbytes.Fragments.FragmentAbout;
import com.megliosolutions.bitsnbytes.Fragments.FragmentContact;
import com.megliosolutions.bitsnbytes.Fragments.FragmentHome;
import com.megliosolutions.bitsnbytes.Fragments.FragmentProducts;
import com.megliosolutions.bitsnbytes.Fragments.FragmentServices;
import com.megliosolutions.bitsnbytes.Fragments.FragmentWarranties;
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
private ActionBarDrawerToggle mDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
if(position == 0) {
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentHome.newInstance())
.commit();
}
else if(position == 1){
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentServices.newInstance())
.commit();
}
else if(position == 2){
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentProducts.newInstance())
.commit();
}
else if(position == 3){
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentWarranties.newInstance())
.commit();
}
else if(position == 4){
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentContact.newInstance())
.commit();
}
else if(position == 5){
fragmentManager.beginTransaction()
.replace(R.id.container, FragmentAbout.newInstance())
.commit();
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4:
mTitle = getString(R.string.title_section4);
break;
case 5:
mTitle = getString(R.string.title_section5);
break;
case 6:
mTitle = getString(R.string.title_section6);
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
Now there is an issue with the FragmentContact.newInstance() in onNavigationDrawerItemSelected()
06-28 15:35:24.695 11744-11744/com.megliosolutions.bitsnbytes E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.megliosolutions.bitsnbytes, PID: 11744
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.view.ViewPager.setAdapter(android.support.v4.view.PagerAdapter)' on a null object reference
at com.megliosolutions.bitsnbytes.Fragments.FragmentContact.LoadTabs(FragmentContact.java:55)
at com.megliosolutions.bitsnbytes.Fragments.FragmentContact.onCreateView(FragmentContact.java:43)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
from logcat Error its clear ViewPager not exist in R.layout.fragment_contact. Please verify that.
Since I need to refer to the viewPager in which it exists on activity_main.xml not the current fragment, I manage to solve this error:
I added a declaration for a new view referring to the activity where the ViewPager exists as following:
View viewNext = inflater.inflate(R.layout.activity_main, container, false);
Then, I declared the viewPager with regards the above declaration:
viewPager = (ViewPager) viewNext.findViewById(R.id.viewPager);
After that, I set up the adaptor.
I have two screens.
Screen 1:
It has two edit text fields. And a button.When I press button, it loads, screen 2.
Screen 2:
It has only dummy static text.
Now, when I enter some field and click on button, it loads screen 2. This is desired. However, when I press back button, I should have the edit text fields cleared as it starts calling lifecycle methods from onCreateView.
But, what I found is, it has edit text content lying over there only. It did not clear the text. Debugging the code, made me realize that, putting the break point on the first line of onCreateView, gives the values as entered last time. After that, onCreateView execution, it is initialized with "" and then in resume, it is replaced with the last entered value.
I want to know that reason.
Activity:
package com.meditab.testproject;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity implements
BlankFragment.ButtonClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating an object of the Fragment Main Class.
BlankFragment blankFragment = new BlankFragment();
// Fragment transaction to replace the fragment.
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frmLayout, blankFragment, "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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onButtonClicked() {
Fragment fragment = new MainActivityFragment();
// Fragment transaction to replace the fragment.
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frmLayout, fragment, "Fragment");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
Fragment A:
package com.meditab.testproject;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* Use the {#link FragmentA#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentA 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 ButtonClickListener buttonClickListener;
public FragmentA() {
// 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 FragmentA.
*/
// TODO: Rename and change types and number of parameters
public static FragmentA newInstance(String param1, String param2) {
FragmentA fragment = new FragmentA();
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) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_a, container, false);
Button btnClick = (Button) view.findViewById(R.id.btnClick);
btnClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonClickListener.onButtonClicked();
}
});
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
buttonClickListener = (ButtonClickListener) activity;
}
#Override
public void onDetach() {
super.onDetach();
}
public interface ButtonClickListener {
void onButtonClicked();
}
}
Fragment B:
package com.meditab.testproject;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentB extends Fragment {
public FragmentB() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_b, container, false);
}
}
that is the default behavior.
before onDrestroyView the view hierarchy state is saved by the fragment manager.
when going back the fragment manager restores that state, and that includes the text that was in the edit text.
you can override public void onViewStateRestored (Bundle savedInstanceState) to know when the state have been restored. Also note from the docs:
This is called after onActivityCreated(Bundle) and before onStart().
so, if you really need to clean the state on can do it during onStart for example. But remember that in general that is a bad user experience.
I am basically having the exact same problem as OP here: How to change fragments using Android navigation drawer
Also using the Template for an navigation drawer activity in Android Studio.
I tried Dreagan's answer, but I am now stuck with a cycle of errors.
Here is my code
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.DrawerLayout;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class MainActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Fragment fragment = new NewsfeedFragment();
FragmentManager fragmentManager = getFragmentManager();
Bundle args = new Bundle();
args.putInt(NewsfeedFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);
switch(position){
case 0:
fragment = new NewsfeedFragment();
break;
case 1:
fragment = new NewsfeedFragment();
break;
}
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
If I run the code as it is here I get following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{dk.gruppe2.jammerbugtevent/dk.gruppe2.jammerbugtevent.MainActivity}: java.lang.ClassCastException: dk.gruppe2.jammerbugtevent.MainActivity#429e4a70 must implement OnFragmentInteractionListener
When I implement OnFragmentInteractionListener, I get the following error:
Error:(22, 9) error: MainActivity is not abstract and does not override abstract method onFragmentInteraction(Uri) in OnFragmentInteractionListener
When i declare MainActivity as abstract, i get this error:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{dk.gruppe2.jammerbugtevent/dk.gruppe2.jammerbugtevent.MainActivity}: java.lang.InstantiationException: can't instantiate class dk.gruppe2.jammerbugtevent.MainActivity
I am very new to android, and not exactly an expert regarding programming to begin with. Any help would be much appreciated. Thanks In advance.
Here is an explanation of things!
Reading your code i did not see any class cast exception... You are casting your activity to the interface OnFragmentInteractionListener. Maybe in one of the fragments.
Also:
When I implement OnFragmentInteractionListener, I get the following
error:
Error:(22, 9) error: MainActivity is not abstract and does not
override abstract method onFragmentInteraction(Uri) in
OnFragmentInteractionListener
When you implement the OnFragmentInteractionListener you must also Override the method: onFragmentInteraction(Uri).
It looks like you aren't setting the fragment's correctly:
#Override
public void onNavigationDrawerItemSelected(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
switch(position)
{
case 0:
fragmentManager.beginTransaction()
.replace(R.id.container, MainListFragment.newInstance())
.commit();
break;
case 1:
fragmentManager.beginTransaction()
.replace(R.id.container, Fragment2.newInstance())
.commit();
case 2:
fragmentManager.beginTransaction()
.replace(R.id.container, Fragment3.newInstance())
.commit();
break;
}
}
Try using this format, as it stands, you aren't using the new instance method you've defined in the fragment.
I found that I only implemented the interfaces, but still needed to implement the methods from the interfaces