Switch fragments through spinner in toolbar - android-fragments

This is driving me crazy. I'm trying to switch fragments by using a spinner, but I can't figure out where my mistake is. When I click on one of the spinner items, it always shows me the content of fragment 3, the others will not appear.
I browsed through the internet for hours now, but couldn't find a understandable solution for my problem, since I'm new to android programming.
Thankful for any help!
MainActivity.java
// Setup spinner
Spinner spinner = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(new MyAdapter(
toolbar.getContext(),
new String[]{
"Fragment 1",
"Fragment 2",
"Fragment 3"
}));
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// When the given dropdown item is selected, show its contents in the
// container view.
switch (position) {
case 0:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment1.newInstance()).commit();
case 1:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment2.newInstance()).commit();
default:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment3.newInstance()).commit();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Fragment1.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1Fragment extends Fragment {
public static Fragment1Fragment newInstance() {
Fragment1Fragment fragment = new Fragment1Fragment();
return fragment;
}
public Fragment1Fragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_fragment1, container, false);
return rootView;
}
}

My dear,
switch (position) {
case 0:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment1.newInstance()).commit();
break;
case 1:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment2.newInstance()).commit();
break;
default:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment3.newInstance()).commit();
break;
}
Without break statement your all 3 lines executed. So the 3rd Fragment.

Related

Interacting with custom CellFactory node adds row to TableView selection list?

I have a TableView with a CellFactory that places a ComboBox into one of the columns. The TableView has SelectionMode.MULTIPLE enabled but it is acting odd with the ComboBox cell.
When the users clicks on the ComboBox to select a value, that row is added to the list of selected rows. Instead, clicking on the ComboBox should either select that row and deselect all others (unless CTRL is being held), or it should not select the row at all, but only allow for interaction with the ComboBox.
I am not sure how to achieve this.
Here is a complete example to demonstrate the issue:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
enum Manufacturer {
HP, DELL, LENOVO, ASUS, ACER;
}
public class TableViewSelectionIssue extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
// Simple TableView
TableView<ComputerPart> tableView = new TableView<>();
TableColumn<ComputerPart, Manufacturer> colManufacturer = new TableColumn<>("Manufacturer");
TableColumn<ComputerPart, String> colItem = new TableColumn<>("Item");
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
colManufacturer.setCellValueFactory(t -> t.getValue().manufacturerProperty());
colItem.setCellValueFactory(t -> t.getValue().itemNameProperty());
tableView.getColumns().addAll(colManufacturer, colItem);
// CellFactory to display ComboBox in colManufacturer
colManufacturer.setCellFactory(param -> new ManufacturerTableCell(colManufacturer, FXCollections.observableArrayList(Manufacturer.values())));
// Add sample items
tableView.getItems().addAll(
new ComputerPart("Keyboard"),
new ComputerPart("Mouse"),
new ComputerPart("Monitor"),
new ComputerPart("Motherboard"),
new ComputerPart("Hard Drive")
);
root.getChildren().add(tableView);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("Sample");
primaryStage.show();
}
}
class ComputerPart {
private final ObjectProperty<Manufacturer> manufacturer = new SimpleObjectProperty<>();
private final StringProperty itemName = new SimpleStringProperty();
public ComputerPart(String itemName) {
this.itemName.set(itemName);
}
public Manufacturer getManufacturer() {
return manufacturer.get();
}
public void setManufacturer(Manufacturer manufacturer) {
this.manufacturer.set(manufacturer);
}
public ObjectProperty<Manufacturer> manufacturerProperty() {
return manufacturer;
}
public String getItemName() {
return itemName.get();
}
public void setItemName(String itemName) {
this.itemName.set(itemName);
}
public StringProperty itemNameProperty() {
return itemName;
}
}
class ManufacturerTableCell extends TableCell<ComputerPart, Manufacturer> {
private final ComboBox<Manufacturer> cboStatus;
ManufacturerTableCell(TableColumn<ComputerPart, Manufacturer> column, ObservableList<Manufacturer> items) {
this.cboStatus = new ComboBox<>();
this.cboStatus.setItems(items);
this.cboStatus.setConverter(new StringConverter<Manufacturer>() {
#Override
public String toString(Manufacturer object) {
return object.name();
}
#Override
public Manufacturer fromString(String string) {
return null;
}
});
this.cboStatus.disableProperty().bind(column.editableProperty().not());
this.cboStatus.setOnShowing(event -> {
final TableView<ComputerPart> tableView = getTableView();
tableView.getSelectionModel().select(getTableRow().getIndex());
tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);
});
this.cboStatus.valueProperty().addListener((observable, oldValue, newValue) -> {
if (isEditing()) {
commitEdit(newValue);
column.getTableView().refresh();
}
});
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
#Override
protected void updateItem(Manufacturer item, boolean empty) {
super.updateItem(item, empty);
setText(null);
if (empty) {
setGraphic(null);
} else {
this.cboStatus.setValue(item);
this.setGraphic(this.cboStatus);
}
}
}
The example begins with a predictable UI:
However, when interacting with the ComboBox in the Manufacturer column, the corresponding row is selected. This is expected for the first row, but it does not get deselected when interacting with another ComboBox.
How can I prevent subsequent interactions with a ComboBox from adding to the selected rows? It should behave like any other click on a TableRow, should it not?
I am using JDK 8u161.
Note: I understand there is a ComboBoxTableCell class available, but I've not been able to find any examples of how to use one properly; that is irrelevant to my question, though, unless the ComboBoxTableCell behaves differently.
Since you want an "always editing" cell, your implementation should behave more like CheckBoxTableCell than ComboBoxTableCell. The former bypasses the normal editing mechanism of the TableView. As a guess, I think it's your use of the normal editing mechanism that causes the selection issues—why exactly, I'm not sure.
Modifying your ManufactureTableCell to be more like CheckBoxTableCell, it'd look something like:
class ManufacturerTableCell extends TableCell<ComputerPart, Manufacturer> {
private final ComboBox<Manufacturer> cboStatus;
private final IntFunction<Property<Manufacturer>> extractor;
private Property<Manufacturer> property;
ManufacturerTableCell(IntFunction<Property<Manufacturer>> extractor, ObservableList<Manufacturer> items) {
this.extractor = extractor;
this.cboStatus = new ComboBox<>();
this.cboStatus.setItems(items);
// removed StringConverter for brevity (accidentally)
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
cboStatus.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
if (event.isShortcutDown()) {
getTableView().getSelectionModel().select(getIndex(), getTableColumn());
} else {
getTableView().getSelectionModel().clearAndSelect(getIndex(), getTableColumn());
}
event.consume();
});
}
#Override
protected void updateItem(Manufacturer item, boolean empty) {
super.updateItem(item, empty);
setText(null);
clearProperty();
if (empty) {
setGraphic(null);
} else {
property = extractor.apply(getIndex());
Bindings.bindBidirectional(cboStatus.valueProperty(), property);
setGraphic(cboStatus);
}
}
private void clearProperty() {
setGraphic(null);
if (property != null) {
Bindings.unbindBidirectional(cboStatus.valueProperty(), property);
}
}
}
And you'd install it like so:
// note you could probably share the same ObservableList between all cells
colManufacturer.setCellFactory(param ->
new ManufacturerTableCell(i -> tableView.getItems().get(i).manufacturerProperty(),
FXCollections.observableArrayList(Manufacturer.values())));
As already mentioned, the above implementation bypasses the normal editing mechanism; it ties the value of the ComboBox directly to the model item's property. The implementation also adds a MOUSE_PRESSED handler to the ComboBox that selects the row (or cell if using cell selection) as appropriate. Unfortunately, I'm not quite understanding how to implement selection when Shift is down so only "Press" and "Shortcut+Press" is handled.
The above works how I believe you want it to, but I could only test it out using JavaFX 12.

OnClickListener in ListView updates a different item on the list

I have a ListView in my Fragment class. This ListView has three items, and every item in the ListView has two buttons, btn+ and btn-, and a TextView.
When I run the app and press the btn+ in the first item, I don't know why but the value of the TextView in the last item is incremented. When I click the btn-, again the value of the last TextView is decremented.
This is my adapter:
package com.example.lie_.tablayout;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import com.iarcuschin.simpleratingbar.SimpleRatingBar;
import java.util.ArrayList;
/**
* Created by Ali on 17/08/2017.
*/
public class MenuListPizzaAdapter extends BaseAdapter {
View vv;
TextView txtOrderNUM;
int counter=0;
private ArrayList <BuyMenuListPizza> BuyMenuListPizza;
private Context C;
public MenuListPizzaAdapter(Context c, ArrayList<BuyMenuListPizza> BuyMenuListPizza) {
this.BuyMenuListPizza = BuyMenuListPizza;
this.C=c;
}
#Override
public int getCount() {
return BuyMenuListPizza.size();
}
#Override
public Object getItem(int i) {
return BuyMenuListPizza.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int position, View View, ViewGroup parent)
{
if (View == null) {
View = LayoutInflater.from(C).inflate(R.layout.buy_menu_list_pizza, parent, false);
}
TextView txtitemname = (TextView)View.findViewById(R.id.txtitemname);
SimpleRatingBar ratingbar = (SimpleRatingBar)View.findViewById(R.id.ratingbar);
final TextView txtitemcontent = (TextView)View.findViewById(R.id.txtitemcontent);
ImageView btnOrderADD = (ImageView)View.findViewById(R.id.btnOrderADD);
ImageView btnOrderDEL = (ImageView)View.findViewById(R.id.btnOrderDEL);
ImageView imgitem = (ImageView)View.findViewById(R.id.imgitem);
txtitemname.setText(BuyMenuListPizza.get(position).getName());
ratingbar.setRating(BuyMenuListPizza.get(position).getRating());
txtitemcontent.setText(BuyMenuListPizza.get(position).getContents());
btnOrderADD.setImageResource(BuyMenuListPizza.get(position).getImgplus());
btnOrderDEL.setImageResource(BuyMenuListPizza.get(position).getImgminues());
imgitem.setImageResource(BuyMenuListPizza.get(position).getImgpizza());
Toast.makeText(parent.getContext(),"Position getView : " + position,Toast.LENGTH_LONG).show();
txtOrderNUM = (TextView)View.findViewById(R.id.txtOrderNUM);
txtOrderNUM.setText(BuyMenuListPizza.get(position).getCount() + "");
btnOrderADD.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int coun= BuyMenuListPizza.get(position).getCount();
coun++;
txtOrderNUM.setText( coun+"");
}
});
btnOrderDEL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int coun= BuyMenuListPizza.get(position).getCount();
coun--;
if(coun<0){
}
else
txtOrderNUM.setText(coun+"");
}
});
return View;
}
}
This is my Fragment class :
public class Pizza extends Fragment {
TextView txtOrderNUM;
ArrayList<BuyMenuListPizza> arrayList;
ListView MenuPizzaList;
Context c;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View android = inflater.inflate(R.layout.pizza, container, false);
MenuPizzaList = ( ListView)android.findViewById(R.id.MenuPizzaList);
arrayList=BuyMenuListPizzaCollection.getBuyMenuListPizza();
MenuPizzaList.setAdapter(new MenuListPizzaAdapter(container.getContext(),arrayList));
// MenuPizzaList.setOnItemClickListener(new oncitemlicklistener());
return android;
}
Please don't say go to xml file and change attribute because I changed that and my code is running and OnClickListener is ok but it doesn't work correctly.
I have searched for more than several days and I didn't find anything.
i found problem solving use : notyficationitemselected(getadapterposition)

Adding Gridview to fragment it's crashing

I'm following a tutorial and trying to build in a grid view into my fragment and every time I launch the app it crashes. I opened up LogCat and it gives me nothing... Can someone help me find out what I can do to get this to display correctly and not crash the app? Thank you!!!
Below I've included my Main Activity, GridView Adapter and Fragment...
MainActivity
import android.app.Activity;
import android.os.Bundle;
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;
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 Char
Sequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
// Set the first title
mTitle = "Inventory";
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
// Remove shadow under actionbar
getSupportActionBar().setElevation(0);
}
#Override
public void onNavigationDrawerItemSelected(int position) {
Fragment objFragment = null;
switch (position) {
case 0:
objFragment = new Inventory_Fragment();
mTitle = getString(R.string.title_section1);
break;
case 1:
objFragment = new Orders_Fragment();
mTitle = getString(R.string.title_section2);
break;
case 2:
objFragment = new Cart_Fragment();
mTitle = getString(R.string.title_section3);
break;
case 3:
objFragment = new Settings_Fragment();
mTitle = getString(R.string.title_section4);
break;
}
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, objFragment)
.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;
}
}
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();
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.inventory_layout, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
// MARK: - Helpers
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
}
GridViewAdapter
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
/**
* Created by kenbarlow on 5/20/15.
*/
public class GridViewAdapter extends BaseAdapter {
private Context context;
public GridViewAdapter(Context context) {
context = context;
}
private int[] icons = {
// Temporary
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
R.drawable.image6,
R.drawable.image7,
R.drawable.image8,
R.drawable.image9,
R.drawable.image10,
R.drawable.image11,
R.drawable.image12,
R.drawable.image13,
R.drawable.image14,
R.drawable.image15,
R.drawable.image16,
R.drawable.image17
};
#Override
public int getCount() {
return icons.length;
}
#Override
public Object getItem(int position){
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(100, 100));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(10, 10, 10, 10);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(icons[position]);
return imageView;
}
}
Inventory_Fragment --- I Feel like the problem is in here but I'm not sure.
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
/**
* Created by kenbarlow on 5/19/15.
*/
public class Inventory_Fragment extends Fragment {
View rootView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.inventory_layout, container, false);
GridView gridview = (GridView) getActivity().findViewById(R.id.gridview);
gridview.setAdapter(new GridViewAdapter(this));
return rootView;
}
}
I guess your are trying to find a gridview in the activity's layout, which is wrong because the gridview is in the Fragment's layout.
Please change in your fragment code:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.inventory_layout, container, false);
GridView gridview = (GridView) rootView.findViewById(R.id.gridview);
if(gridview != null){
gridview.setAdapter(new GridViewAdapter(getActivity()));
}
return rootView;
}
If it's not the cause of the problem, please post a stacktrace when the crash happen (it should have already been done).
I have not looked at all the code yet. I reviewed GridViewAdapter and Inventory_Fragment.
Remove getItemId method in GridViewAdapter. You don't use it anyway. It is possible that the BaseAdapter is referencing it, and returning it null from that method may crash the adapter.
Code suggestion, return an item for this method:
#Override
public Object getItem(int position){
return icons[position];
}
LogCat and it gives me nothing...
if literally nothing, try to reset LogCat.
as i see in these lines
rootView = inflater.inflate(R.layout.inventory_layout, container, false);
GridView gridview = (GridView) getActivity().findViewById(R.id.gridview);
you are inflating and makeing rootView to find your inner layouts. so instead of getActivity() in second line use your rootView.
and remember to put your gridView layout inside inventory_layout
I am not sure if it is the only issue or not, but this one looks a bit wrong.
In your Inventory_Fragment class:
gridview.setAdapter(new GridViewAdapter(this));
You should change it to this:
gridview.setAdapter(new GridViewAdapter(getActivity()));
Also please upload your layouts and/or logcat report here. It is hard to go through the code like this.

Viewpager tabs recreated?

I have implemented a NavigationDrawer with a few items in it. Every item represents a different Fragment and one of them has tabs. My problem is that every time I open this Fragment the tabs reloaded! and added to the previous tabs. Why is this happening and how can I solve it?
This is the Fragment with the tabs:
public class fragment_profilo_tabs extends Fragment implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
String[] tabs = { "Profilo aziendale", "Credenziali" };
/* (non-Javadoc)
* #see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
*/
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
// Initilization
View view = View.inflate(getActivity(), R.layout.profilo_tabs, null);
viewPager = (ViewPager) view.findViewById(R.id.pager);
actionBar = getActivity().getActionBar();
mAdapter = new TabsPagerAdapter(getFragmentManager());
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(this));}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
return view;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
And this is my ViewPagerAdapter:
public class TabsPagerAdapter extends FragmentPagerAdapter {
/* (non-Javadoc)
* #see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object)
*/
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return POSITION_NONE;
}
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new fragment_profilo_modificaProfilo();
case 1:
// Games fragment activity
return new fragment_profilo_credenzialiAccesso();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Ok there are multiple issues. First and foremost lets talk about your ViewPagerAdapter:
The first thing that caught my eye is this:
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return POSITION_NONE;
}
This is very bad for performance. I know that some posts on Stack Overflow suggest using this to "fix" a few things, but that is not the way to go. Remove this, you don't need it.
But the main issue is in your Fragment. First and foremost this:
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab()
.setText(tab_name)
.setTabListener(this));
}
You are adding tabs to the ActionBar. And the ActionBar is not part of you Fragment. Each time you display this Fragment you add the same tabs to the ActionBar but you never remove them again or anything.
My advice: Don't do this. Open a new Activity for the tabs Fragment. This should clearly not be in the same Activity. I cannot imagine any situation where suddenly adding tabs to the current Activity would satisfy the Android Platform Guidelines or provide good usability.
The general rule is that everything that has to do with the Activity itself - like things concerning the ActionBar or tabs in the ActionBar - should be handled in the Activity. Code which adds tabs to the ActionBar has no place inside a Fragment. So either add the tabs permanently in onCreate() of your Activity. Or create a new Activity with those tabs especially for the fragment_profilo_tabs.
As an aside: class names should never be Snake Case. Start class names with an uppercase letter and use Camel Case. Everything else will just confuse other programmers looking at your code

Which lifecycle callback is called when a fragment pager adapter's fragment comes to screen?

I want to detect when a particular fragment of three fragments I have set up with a ViewPager comes on to screen. I have 3 fragments in the viewpager and have set up the viewpager with
mViewPager.setOffscreenPageLimit(2);
so all three fragments are constructed at once (since it stores 2 on each side). I checked that Fragment.onResume() is called just once and not when each fragment comes to the foreground. Is there another callback to ensure I can catch this event and send some analytics signal for it?
Thanks
You can use the ViewPager.setOnPageChangeListener() to set a ViewPager.OnPageChangeListener().
Use the listener for the selected page based on its position in the PagerAdapter.
Here's my sample app:
package net.ynotapps.testviewpagerfragment;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.ButterKnife;
import butterknife.InjectView;
public class MainActivity extends ActionBarActivity {
#InjectView(R.id.pager)
ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
CustomPagerAdapter adapter = new CustomPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// Put Code here //
// Example code //
if (position == 2) {
Toast.makeText(MainActivity.this, "Found Position 2 fragment", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
public static class CustomPagerAdapter extends FragmentPagerAdapter {
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
CustomFragment fragment = new CustomFragment();
Bundle bundle = new Bundle();
bundle.putString("display_text", String.format("Fragment %d is here.", position));
fragment.setArguments(bundle);
return fragment;
}
#Override
public int getCount() {
return 5;
}
}
public static class CustomFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
TextView tv = new TextView(getActivity());
tv.setText(getArguments().getString("display_text"));
return tv;
}
}
}
ViewPager source code:
// Dispatch the change to any listeners
if (mAdapterChangeListeners != null && !mAdapterChangeListeners.isEmpty()) {
for (int i = 0, count = mAdapterChangeListeners.size(); i < count; i++) {
mAdapterChangeListeners.get(i).onAdapterChanged(this, oldAdapter, adapter);
}
}
So, you can use the ViewPager.addOnAdapterChangeListener to listen the callback.

Resources