I'm trying to update textview in fragment from another activity. But I'm getting a NUllPointerException when calling the setText method. I have tried the following, but still getting the NPE.
1. Tried accessing the fragments textview with FindViewbyId in activity.
2. Tried using a method in fragment and calling it from activity and passing the value as parameters
FragHome Activity
public class FragHome extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
Handler bluetoothIn;
private static TextView tmpF, humF, CoF;
String tempGL, HumGL, coGL, devname;
double dblTemp, dblCo;
final int handlerState = 0; // used to identify handler message
private BluetoothAdapter btAdapter = null;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frag_home);
//Adding toolbar to the activity
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing the tablayout
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
//Initializing viewPager
viewPager = (ViewPager) findViewById(R.id.pager);
//Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Temperature"));
tabLayout.addTab(tabLayout.newTab().setText("Humidity"));
tabLayout.addTab(tabLayout.newTab().setText("CO"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
//Creating our pager adapter
Pager adapter = new Pager(getSupportFragmentManager(), tabLayout.getTabCount());
//Adding adapter to pager
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
//Adding onTabSelectedListener to swipe views
tabLayout.setOnTabSelectedListener(this);
bluetoothIn=new Handler() {
String readMessage;
String[] values = new String[]{""};
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
readMessage = (String) msg.obj;
values = readMessage.split("#");
for (int j = 0; j < values.length; j++) {
int rem = j % 3;
if (rem == 0) {
tmpF.setText(values[j] + " C");
tempGL = String.valueOf(values[j]);
try {
dblTemp = Double.parseDouble(tempGL);
} catch (NumberFormatException e) {
e.printStackTrace();
}
} else if (rem == 1) {
CoF.setText(values[j] + " ppm");
coGL = values[j];
try {
dblCo = Double.parseDouble(coGL);
} catch (NumberFormatException e) {
e.printStackTrace();
}
} else if (rem == 2) {
humF.setText(values[j] + " %");
HumGL = values[j];
}
}
}
}
};
btAdapter=BluetoothAdapter.getDefaultAdapter(); // get Bluetooth
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
// mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
Pager
public class Pager extends FragmentStatePagerAdapter {
//integer to count number of tabs
int tabCount;
//Constructor to the class
public Pager(FragmentManager fm, int tabCount) {
super(fm);
//Initializing tab count
this.tabCount= tabCount;
}
//Overriding method getItem
#Override
public Fragment getItem(int position) {
//Returning the current tabs
switch (position) {
case 0:
Tab1 tab1 = new Tab1();
return tab1;
case 1:
Tab2 tab2 = new Tab2();
return tab2;
case 2:
Tab3 tab3 = new Tab3();
return tab3;
default:
return null;
}
}
//Overriden method getCount to get the number of tabs
#Override
public int getCount() {
return tabCount;
}
}
Tab1
public class OneFragment extends Fragment {
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_one, container, false);
return view;
}
}
fragment_one.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="shinil.tablayout.OneFragment"
android:id="#+id/rltnvnv">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Temperature"
android:textSize="40dp"
android:textStyle="bold"
android:id="#+id/textviewtemp"
android:layout_centerInParent="true"/>
</RelativeLayout>
frag_home.xml
LinearLayout
android:id="#+id/main_layout"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- our toolbar -->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<!-- our tablayout to display tabs -->
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!-- View pager to swipe views -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
The NPE occurs when I try to settext from the activity. Please help
Use below callback:
Fragment Class:
public class FragmentOne extends Fragment {
private ViewCallback mCallback;
public FragmentOne(ViewCallback mCallback) {
this.mCallback = mCallback;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_one, container, false);
mCallback.updateTextView((TextView) view.findViewById(R.id.fragmentTextView));
return view;
}
public interface ViewCallback {
void updateTextView(TextView view);
}
}
Below is the Activity class:
public class MainCallbackActivity extends Activity implements CallbackFragment.ViewCallback {
public TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_callback);
FragmentOne fragment = new FragmentOne(this);
getFragmentManager().beginTransaction().add(R.id.frameLayout, fragment).commit();
}
#Override
protected void onResume() {
super.onResume();
if (textView != null)
textView.setText("Updating Fragment TextView in Activity..!!");
}
#Override
public void updateTextView(TextView view) {
this.textView = view;
}
}
Implment that call back in your activity class..then update the textview.
Related
I currently have this tab view which I followed from this tutorial. Everything works fine until I noticed that the onCreateView is not called on any of the tab. I've looked around here and there for solution but I still can't solve.
Here is my code:
activity_pref_main_container.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PrefActivityMain">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
</RelativeLayout>
PrefMainActivity.class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pref_main_container);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(R.string.preference_title);
setSupportActionBar(toolbar);
new PrefActivityListAsync(this,this,specialization).execute();
new PrefActivityListAsync(this,this,position).execute();
new PrefActivityListAsync(this,this,type).execute();
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Specialization"));
tabLayout.addTab(tabLayout.newTab().setText("Position"));
tabLayout.addTab(tabLayout.newTab().setText("Type"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PrefAdapter adapter = new PrefAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.setOffscreenPageLimit(2);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
PrefAdapder.class
public class PrefAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
public PrefAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
PrefActivitySpecialization tab1 = new PrefActivitySpecialization();
return tab1;
case 1:
PrefActivityPosition tab2 = new PrefActivityPosition();
return tab2;
case 2:
PrefActivityType tab3 = new PrefActivityType();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return 0;
}
}
one out of three fragment class
PrefActivitySpecialization.class
public class PrefActivitySpecialization extends
android.support.v4.app.Fragment {
private ArrayList<DataPrefSpecialization> dataPrefSpecializationArrayList;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup
container, Bundle savedInstanceState) {
View view =
inflater.inflate(R.layout.activity_pref_specialization_container, container,
false);
dataPrefSpecializationArrayList = ((PrefActivityMain)
getActivity()).getDataPrefSpecialization();
for(int i = 0; i < dataPrefSpecializationArrayList.size(); i++){
Log.d("Check Specialization
",dataPrefSpecializationArrayList.get(i).getName());
}
return inflater.inflate(R.layout.activity_pref_specialization_container, container, false);
}
}
You should make changes at two place:
1) Change
#Override
public int getCount() {
return 0;
}
to
#Override
public int getCount() {
return mNumOfTabs;
}
2) Change
return inflater.inflate(R.layout.activity_pref_specialization_container, container, false);
to
return view;
public PrefAdapter(FragmentManager fm, int NumOfTabs)
You must declare Count No NumOfTabs
int getCount ()-> How many items are in the data set represented by this
Adapter.
#Override
public int getCount()
{
return mNumOfTabs;
}
Do not'
return inflater.inflate(R.layout.activity_pref_specialization_container, container, false);
Do
return view ;
Your getCount() method is returning 0;
There is another (possibly easier) way to connect the view pager with the tab layout-
First, in your PrefAdapter class, override the getPageTitle() method and return your tab titles for the respective tab positions from there.
In your PrefMainActivity class, remove all the lines like-
tabLayout.addTab(...)
Add the following line instead-
tabLayout.setupWithViewPager(viewPager);
TabLayout.OnTabSelectedListener has one callback which is onTabReselected(TabLayout.Tab tab)
We can reselect tab manually by tapping on selected tab again.
So my question is how to reselect tab programatically?
This is how I got my tabs working
Layout for tabs:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#ffffff">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:layout_collapseMode="pin"
android:background="#000000"
app:titleTextColor="#ffffff"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/PopupMenuStyle">
<TextView
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/textview"
android:textColor="#color/colorTrueWhite"/>
</android.support.v7.widget.Toolbar>
<!-- our tablayout to display tabs -->
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorBlack"
android:minHeight="?attr/actionBarSize"
app:tabIndicatorColor="#color/colorTrueWhite"
app:tabIndicatorHeight="5dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!-- View pager to swipe views -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
Activity using that layout:
public class Main2Activity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
private TabLayout tabLayout;
public static ViewPager viewPager;
public static Context ctx;
Pager adapter;
public static int expired, paid;
Boolean isConnection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(tb);
TextView tv = (TextView) findViewById(R.id.textview);
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ctx = getApplicationContext();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.addTab(tabLayout.newTab().setText("title1"));
tabLayout.addTab(tabLayout.newTab().setText("title2"));
tabLayout.addTab(tabLayout.newTab().setText("title3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setupWithViewPager(viewPager);
adapter = new Pager(getSupportFragmentManager(), tabLayout.getTabCount(), ctx);
viewPager.setAdapter(adapter);
if(some condition)
{
viewPager.setCurrentItem(2);
}
else
{
viewPager.setCurrentItem(1);
}
viewPager.setOffscreenPageLimit(2);
tabLayout.addOnTabSelectedListener(this);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(Typeface.DEFAULT, Typeface.BOLD);
}
}
}
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
}
Pager code:
public class Pager extends FragmentStatePagerAdapter
{
int tabcount;
Context ctx;
private String [] Titles = {"title1", "title2", "title3"};
public Pager(FragmentManager fm, int tabcount, Context ctx)
{
super(fm);
this.tabcount = tabcount;
this.ctx = ctx;
}
#Override
public int getCount() {
return tabcount;
}
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Tab1 tab1 = new Tab1();
return tab1;
case 1:
Tab2 tab2 = new Tab2();
return tab2;
case 2:
Tab3 tab3 = new Tab3();
return tab3;
default:
return null;
}
}
}
I'm making an app and the Main Activity has a tablayout connected to a viewpager. This viewpager has three fragments.
I know that the viewpager adapter manages 3 fragments (the correct amount) because I used Logging statements. Also, I use asyncTasks to load data into the fragments and it is done correctly. When the data is loaded, it populates a recyclerview. I used logging statements and I know that each fragment has a recyclerview with 20 entries, which is correct.
But for some reason, my viewpager does not display the fragments, even though when I call getItemCount() on it, I get the right number of fragments.
Can you help me to figure out why the fragments are being created but not displayed?
Thank you.
This is my MainActivity:
public class MovieListActivity extends AppCompatActivity {
public static final String POPULAR = "popular";
public static final String TOP = "top";
public static final String FAVORITES = "favorites";
private static final String QUERY_TYPE = "query type";
private RecyclerView mRecyclerView;
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle(getTitle());
setupTabLayout();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
if (findViewById(R.id.movie_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-w900dp).
// If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
}
}
private void setupTabLayout() {
TabLayout tabLayout = (TabLayout) findViewById(R.id.tablayout);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout.addTab(tabLayout.newTab().setText(POPULAR));
tabLayout.addTab(tabLayout.newTab().setText(TOP));
tabLayout.addTab(tabLayout.newTab().setText(FAVORITES));
List<Fragment> fragments = new ArrayList<>();
for (int i=0;i<3;i++) {
Bundle bundle = new Bundle();
bundle.putInt(QUERY_TYPE, i);
fragments.add(ListFragment
.instantiate(this,ListFragment.class.getName(),bundle));
}
viewPager.setAdapter(new MoviePagerAdapter(getSupportFragmentManager(), fragments));
tabLayout.setupWithViewPager(viewPager);
}
}
This is the fragment that the viewpager should instantiate 3 times:
public class ListFragment extends Fragment {
private static final String QUERY_TYPE = "query type";
public static final int POPULAR = 0;
public static final int HIGHEST_RATED = 1;
public static final int FAVORITES = 2;
private RecyclerView mRecyclerView;
private int mListType;
public ListFragment() {}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
mListType = this.getArguments().getInt(QUERY_TYPE);
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.movie_list,container,false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.movie_list);
assert mRecyclerView != null;
setupRecyclerView(mRecyclerView);
if (mListType == HIGHEST_RATED || mListType == POPULAR) {
requestMovies();
}
return super.onCreateView(inflater, container, savedInstanceState);
}
private void setupRecyclerView(#NonNull RecyclerView recyclerView) {
recyclerView.setAdapter(new MovieAdapter(getActivity()));
}
void setMovies(Movie[] movies) {
MovieAdapter movieAdapter = (MovieAdapter)mRecyclerView.getAdapter();
movieAdapter.setMovies(movies);
movieAdapter.notifyDataSetChanged();
}
private void requestMovies() {
if (mRecyclerView.getAdapter().getItemCount() == 0) {
new FetchMoviesTask(this).execute(POPULAR);
}
}
}
Pager Adapter:
public class MoviePagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragments;
public MoviePagerAdapter(FragmentManager fm, List<Fragment> mFragments) {
super(fm);
this.mFragments = mFragments;
}
#Override
public Fragment getItem(int position) {
return this.mFragments.get(position);
}
#Override
public int getCount() {
return mFragments==null? 0 : mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case ListFragment.POPULAR:
return MovieListActivity.POPULAR;
case ListFragment.HIGHEST_RATED:
return MovieListActivity.TOP;
case ListFragment.FAVORITES:
return MovieListActivity.FAVORITES;
default:
throw new IllegalArgumentException("Requesting a fragment that doesn't exist");
}
}
}
Just in case: these are the xml files for the activity and fragment:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MovieListActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v4.view.ViewPager>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/movie_list"
android:name="com.example.madelenko.app.moviegami.MovieListFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="GridLayoutManager"
app:spanCount="2"
tools:context="com.example.madelenko.app.moviegami.MovieListActivity"
tools:listitem="#layout/movie_list_content" />
return your view which you inflate in Fragment,
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.movie_list,container,false);
return rootView ;
}
I'm creating tab view using tablayout and viewpager. I use one fragment for each tab. And in my MainActivity, I'm getting some values from a device through bluetooth. The values are received as a single string, and I split it and sets it to corresponding tabs. But I'm getting a NullPointerException when I try to call the setText method for the textview in fragment from my activity.
Can anybody show me how to update the textviews of each of the fragments from my MainActivity?? Like, if i select the temperature tab, the textview in the temperature fragment should be updated with the value from MainActivity. Please Help
Activity
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
Handler bluetoothIn;
private static TextView tmpF, humF, CoF;
String tempGL, HumGL, coGL, devname;
double dblTemp, dblCo;
final int handlerState = 0; // used to identify handler message
private BluetoothAdapter btAdapter = null;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frag_home);
tmpF = (TextView)findViewById(R.id.txt_temp_val);
humF = (TextView)findViewById(R.id.txt_hum_val);
co = (TextView)findViewById(R.id.txt_co_val);
//Adding toolbar to the activity
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing the tablayout
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
//Initializing viewPager
viewPager = (ViewPager) findViewById(R.id.pager);
//Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Temperature"));
tabLayout.addTab(tabLayout.newTab().setText("Humidity"));
tabLayout.addTab(tabLayout.newTab().setText("CO"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
//Creating our pager adapter
Pager adapter = new Pager(getSupportFragmentManager(), tabLayout.getTabCount());
//Adding adapter to pager
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
//Adding onTabSelectedListener to swipe views
tabLayout.setOnTabSelectedListener(this);
bluetoothIn=new Handler() {
String readMessage;
String[] values = new String[]{""};
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
readMessage = (String) msg.obj;
values = readMessage.split("#");
for (int j = 0; j < values.length; j++) {
int rem = j % 3;
if (rem == 0) {
tmpF.setText(values[j] + " C");
tempGL = String.valueOf(values[j]);
try {
dblTemp = Double.parseDouble(tempGL);
} catch (NumberFormatException e) {
e.printStackTrace();
}
} else if (rem == 1) {
CoF.setText(values[j] + " ppm");
coGL = values[j];
try {
dblCo = Double.parseDouble(coGL);
} catch (NumberFormatException e) {
e.printStackTrace();
}
} else if (rem == 2) {
humF.setText(values[j] + " %");
HumGL = values[j];
}
}
}
}
};
btAdapter=BluetoothAdapter.getDefaultAdapter(); // get Bluetooth
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
// mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
Tab1
public class OneFragment extends Fragment {
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_one, container, false);
return view;
}
}
fragment_one.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="shinil.tablayout.OneFragment"
android:id="#+id/rltnvnv">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Temperature"
android:textSize="40dp"
android:textStyle="bold"
android:id="#+id/txt_temp_val"
android:layout_centerInParent="true"/>
</RelativeLayout>
Logcat
Caused by: 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 shinil.airopure.MainActivity.onCreate(MainActivity.java:194)
frag_home.xml
<LinearLayout
android:id="#+id/main_layout"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
Hi i'm not sure if i understand your problem correctly but let me try to help.
I assume your ViewPager adapter extends from FragmentStatePagerAdapter
First in your Pager adapter define a SparseArray for your fragments like below:
SparseArray<Fragment> myPagerFragments= new SparseArray<>();
In your adapter's instantiateItem method add your fragment to your sparsearray.
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
myPagerFragments.put(position, fragment);
return fragment;
}
And in your destroyItem method remove your fragment from your sparsearray.
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
myPagerFragments.remove(position);
super.destroyItem(container, position, object);
}
Add a method to your adpater which returns your pager fragment likew below:
public Fragment getRegisteredFragment(int position) {
return myPagerFragments.get(position);
}
In your fragments define a public method which changes your TextView's text likew below:
public void setText(String text){
myTextView.setText(text);
}
In your activity define your adapter and add an onPageChangeListener to your ViewPager like below:
MyPagerAdapter mAdapter = new MyPagerAdapter(context,items);
myViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Fragment myPagerFragment = mAdapter.getRegisteredFragment(position);
if(fragment != null){
((YourFragment)fragment).setText("Hello World!");
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
I hope this'll help you. Good luck.
I am trying to implement Tabs with swipe using ViewPager and 4 Fragments. When I swipe the tabs the respective xml layouts of the fragmnets are displayed correctly on each tab but the code of the fragments are not executed correctly.
eg-The following tabs have the respective fragments in it.
Tab0-ButtonFragment
public class ButtonFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_button, container, false);
Log.i("inside", "button fragment");
return rootView;
}
Tab1-ImageFragment
public class ImageFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_image, container, false);
Log.i("inside", "image fragment");
return rootView;
}
Tab2-TextFragment
public class TextFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_text, container, false);
Log.i("inside", "text fragment");
return rootView;
}
Tab3-Test
public class Test extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.temp, container, false);
Log.i("inside", "tessssssssst fragment");
return rootView;
}
When the tabs are displayed
I get the log message for tab0 and tab1 simultaneously. Then after swiping and going to tab1 i get the log message for tab2. After swiping to tab2 i get log message for tab 3 and when tab 3 is reached no log message is dispalyed. Can anyone tell me how can I execute the respective codes for the respective tabs? My remaining codes are as below:
public class TabsPagerAdapter extends FragmentPagerAdapter { //Update - code formatting
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem( int index) {
Log.i("index", "" + index);
switch (index) {
case 0:
// Top Rated fragment activity
return new ButtonFragment();
case 1:
// Games fragment activity
return new ImageFragment();
case 2:
// Movies fragment activity
return new TextFragment();
case 3:
return new Test();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 4;
}
MainActivity
public class MainActivity extends FragmentActivity implements OnTabChangeListener, OnPageChangeListener {
private TabsPagerAdapter mAdapter;
private ViewPager mViewPager;
private TabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
// Tab Initialization
initialiseTabHost();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
// Fragments and ViewPager Initialization
mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(MainActivity.this);
}
// Method to add a TabHost
private static void AddTab(MainActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec) {
tabSpec.setContent(new MyTabFactory(activity));
tabHost.addTab(tabSpec);
}
// Manages the Tab changes, synchronizing it with Pages
public void onTabChanged(String tag) {
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
// Manages the Page changes, synchronizing it with Tabs
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
int pos = this.mViewPager.getCurrentItem();
this.mTabHost.setCurrentTab(pos);
}
#Override
public void onPageSelected(int arg0) {
}
// Tabs Creation
private void initialiseTabHost() {
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
// TODO Put here your Tabs
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("ButtonTab").setIndicator("ButtonTab"));
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("ImageTab").setIndicator("ImageTab"));
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("TextTab").setIndicator("TextTab"));
MainActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("TestingTab").setIndicator("TestingTab"));
mTabHost.setOnTabChangedListener(this);
}
This is default behaviour of viewpager you can not change it as viewpager creates fragments so that the views exist, so the user can swipe between them, so that the old view sliding off the screen and the new view sliding onto the screen. You can write your code like this
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
Log.i("inside", "button fragment");
}else{
// fragment is not visible
}
}
so that when fragment is visible your code execute
When change your tab recall your corresponding fragment.
Try this it will help you
Create TabFragment.java
public class TabFragment extends Fragment implements OnPageChangeListener,
OnTabChangeListener {
private TabHost tabHost;
private int currentTab = 0;
private SwipeDisableViewPager viewPager;
protected TabPagerAdapter pageAdapter;
private List<Fragment> fragments;
private final int TAB_BUTTON=0,TAB_IMAGE=1,TAB_TEXT=2,TAB_TEST=3;
#SuppressWarnings("unchecked")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_tabhost, null);
viewPager = (SwipeDisableViewPager) view.findViewById(R.id.viewpager);
tabHost = (TabHost) view.findViewById(android.R.id.tabhost);
viewPager.addOnPageChangeListener(this);
fragments = new ArrayList<>();
fragments.add(new ButtonFragment());
fragments.add(new ImageFragment());
fragments.add(new TextFragment());
fragments.add(new Test());
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
pageAdapter = new TabPagerAdapter(getChildFragmentManager(), fragments, getArguments());
pageAdapter.notifyDataSetChanged();
viewPager.setAdapter(pageAdapter);
viewPager.setOffscreenPageLimit(3);
setupTabs();
}
private void setupTabs() {
tabHost.setup();
tabHost.addTab(newTab(R.string.home, R.drawable.menu_home_bg));
tabHost.addTab(newTab(R.string.likes, R.drawable.menu_likes_bg));
tabHost.addTab(newTab(R.string.matches, R.drawable.menu_matches_bg));
for (int i = 0; i < tabHost.getTabWidget().getChildCount(); i++) {
tabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
}
tabHost.setOnTabChangedListener(this);
tabHost.setCurrentTab(currentTab);
}
private View getTabIndicator(Context context, int title, int icon) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_view, null);
ImageView iv = (ImageView) view.findViewById(R.id.imageView);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setText(title);
return view;
}
private TabSpec newTab(int tabValue, int icon) {
TabSpec tabSpec = tabHost.newTabSpec(getString(tabValue));
tabSpec.setIndicator(getTabIndicator(tabHost.getContext(), tabValue, icon));
tabSpec.setContent(new Dummy(getActivity()));
return tabSpec;
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int currentPosition, float arg1, int arg2) {
}
#Override
public void onPageSelected(int position) {
if (position == 0)
viewPager.setSwipeEnabled(false);
else
viewPager.setSwipeEnabled(true);
tabHost.setCurrentTab(position);
if (listener != null)
listener.onTabChanged(position);
}
#Override
public void onTabChanged(String tabId) {
currentTab = tabHost.getCurrentTab();
viewPager.setCurrentItem(currentTab);
switch(currentTab){
case TAB_BUTTON:
((ButtonFragment) fragments.get(currentTab)).recall();
break;
case TAB_IMAGE:
((ImageFragment) fragments.get(currentTab)).recall();
break;
case TAB_TEXT:
((TextFragment) fragments.get(currentTab)).recall();
break;
case TAB_TEST:
((Test) fragments.get(currentTab)).recall();
break;
}
}
create tab_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#drawable/menu_bg"
android:fadingEdge="none"
android:gravity="center"
android:showDividers="none"
android:tabStripEnabled="false" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<com.mobellotech.shift.Widget.SwipeDisableViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FFFFFF" />
</LinearLayout>
</TabHost>
Create tab_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="45dp"
android:layout_height="45dp"
android:contentDescription="#string/menu_icon" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Create TabPagerAdaper
public class TabPagerAdapter extends FragmentPagerAdapter {
private Bundle args;
private List<Fragment> fragments;
public TabPagerAdapter(FragmentManager fm, List<Fragment> fragments,
Bundle args) {
super(fm);
this.fragments = fragments;
this.args = args;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = fragments.get(position);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Create MainActivity.java
public class MainActivity extends AppCompatActivity {
protected TabFragment tabFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabFragment = new TabFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, tabFragment).commit();
}
}
Create activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.v4.widget.DrawerLayout>
Finally add the recall method in your fragment class like this
public class ButtonFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_button, container, false);
Log.i("inside", "button fragment");
return rootView;
}
public void recall() {
Log.i("inside", "button fragment");
}
}