I'm trying to modify an old FragmentActivity hosting a view pager with 3 listview in a Fragment.
The Fragment class has code that is similar to an Activity. In fact, when converting an existing Android application to use fragments, I though it would have been sufficient to move code from the activity's callback methods into the respective callback methods of the fragment. But it didn't work. I get a NullPointerException at the line
mViewPager.setAdapter(mAppSectionsPagerAdapter);
here is the code:
public class FragmentAllEvents extends Fragment implements ActionBar.TabListener
{
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
// JSON Node names
private static final String TAG_UID = "uid";
private static final String TAG_LOGO = "logo";
private static final String TAG_POKUID = "pokuid";
static ArrayList<HashMap<String, String>> userList;
ArrayList<HashMap<String, String>> userListTotal;
HashMap<String, String> userSelected;
EventsFunctions eventsFunctions;
UserFunctions userFunctions;
/**
* The {#link ViewPager} that will display the three primary sections of the app, one at a
* time.
*/
ViewPager mViewPager;
static ListView lv;
ActionBar actionBar;
//Context context = this;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
View v = inflater.inflate(R.layout.all_events_main, container, false);
Log.e("AllEventsFragmentActivity Report", "Entering AllEventsFragments");
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
//FragmentManager fm = getSupportFragmentManager();
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getFragmentManager());
// Set up the action bar.
actionBar = getActivity().getActionBar();
// Specify that the Home/Up button should not be enabled, since there is no hierarchical
// parent.
actionBar.setHomeButtonEnabled(true);
// Specify that we will be displaying tabs in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager, attaching the adapter and setting up a listener for when the
// user swipes between sections.
mViewPager = (ViewPager) getActivity().findViewById(R.id.pager_main);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
// Defining a listener for pageChange
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
{
[...]
});
[...]
}
In the previous version of this class I was extending FragmentAllEvents with a FragmentActivity instead of a Fragment.
It appears like, mViewPager is not populated and is NULL. If pager_main is in all_events_main layout, you need to use v.findViewById(R.id.pager_main)
Related
I have two controllers, one controller has a tableview that lists all members and the other controller allows a member to be added. I am having trouble getting the table to update when a member is added. I use two models that are already given to me, so I don't change anything in the models.
Each member has an id and a profession, I use cellValueFactory for listing the members. I tried adding listeners to the cellValueFactoryProperties like this:
idColumn.cellValueFactoryProperty().addListener((obs, oldV, newV) -> memberTv.refresh());
But it still doesn't show new members
The Controller with the TableView:
#FXML
TableColumn<Member, Integer> idColumn;
#FXML
TableColumn<Member, String> profColumn;
#FXML
TableView<Member> memberTv;
#FXML
private void initialize() {
memberTv.setItems(getClub().getMembers());
idColumn.setCellValueFactory(cellData -> new
ReadOnlyObjectWrapper(cellData.getValue().getId()));
profColumn.setCellValueFactory(cellData -> new
ReadOnlyStringWrapper(cellData.getValue().getProf()));
}
public final Club getClub() {
\\\returns Club model
}
The Controller that adds members
private int getId() {
return Integer.parseInt(idTf.getText());
}
private void setId(String id) {
idTf.setText(id);
}
private String getProf() {
return profTf.getText();
}
private void setProf(String prof) {
profTf.setText("" + prof);
}
#FXML
public void handleAddMember(){
getClub().addMember(getId(), getProf());
}
When I add a member I want the TableView to show the added member, but it only shows members already added in the model.
I figured it out, I had a ClubController that sets the stage based after a menu button is clicked. The problem was that whenever I set a stage I used a new instance of teh Club model instead of using getKiosk(). I changed all the new Club()```` to getClub()``` and it everything works perfectly now.
I have 6 fragments, all with the same layout and functionality, the data [A,B,C,D,...] for each fragment is different. When the first two fragments are created I view B,B then C then D...etc. Swiping back from C I get the correct data viewed C, B, A.
I can't see what I am doing wrong. Here is a bit of code :
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
private final Bundle fragmentBundle;
public ScreenSlidePagerAdapter(FragmentManager fm, Bundle data) {
super(fm);
fragmentBundle = data;
}
#Override
public Fragment getItem(int position) {
// creating fragment and passing int position for array and array
return SoundFrag.newInstance(position, fragmentBundle);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
and the fragment class :
public class SoundFrag extends Fragment{
// fragment Id Postion
private int fragPosition;
private static final String KEY_POSITION="fragIntIdP";
static SoundFrag newInstance(int position, Bundle arrayIntS) {
SoundFrag frag=new SoundFrag();
arrayIntS.putInt(KEY_POSITION, position);
frag.setArguments(arrayIntS);
return(frag);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// retrive data from bundle passed by activity
Bundle argsIn = getArguments();
SoundArrayParcel arrayToReceive = argsIn.getParcelable("dataResId");
final int[][] arrayResId = arrayToReceive.getInt();
fragPosition = argsIn.getInt("fragIntIdP");
// inflate the fragment
final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.sounds_frag, container, false);
.....
I believe the problem to be here. The value of fragPosition is always 1 for the first two fragments, instead of 0 and then 1. Why?
Thanks for any help !
For what it's worth...
I changed the code so that the array was no longer passed to the fragment via Bundle. I now only pass the position value of the fragment (from the getItem(int position) method) and the array is 'constructed' within the fragment once it inflates.
The condition I was noticing before (fragposition being 1 for both first and second fragments) no longer happens and the apps displays the information correctly.
Why ? Not sure, but it works. I will however continue to investigate as I don't like the solution I found.
I dont know if my title is correct but I hope you can get my question with the help of some pictures. So I have a project the will display a fragment containing book info such us Title, Author, Publisher etc, at the same time I want to display comments about the book I mean once it loads. It also loads a recyclerview containing the comments about the books like in google play store where you may see the comments of different users. How can I achieve this? I do know how to create a recyclerview. here is the image for more clarity.
For RecyclerView you need to add
compile 'com.android.support:recyclerview-v7:24.2.1'
in your dependencies. Inside module level build.gradle file. After adding the compilation file , sync your project.
Then inside your layout add the recyclerView. Like this
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_funds"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#layout/layout_funds_item" />
here the attribute "listitem" will show how your recyclerview will be seen when items will be inflated.
Now in your activity or fragment initialize the recyclerview.
private RecyclerView mRecyclerView;
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_funds);
After that you need to set the layoutManger for your recyclerview. A LayoutManager is responsible for measuring and positioning item views within a RecyclerView as well as determining the policy for when to recycle item views that are no longer visible to the user. By changing the LayoutManager a RecyclerView can be used to implement a standard vertically scrolling list, a uniform grid, staggered grids, horizontally scrolling collections and more. Several stock layout managers are provided for general use.
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
After that set your adapter to the recyclerview.
mRecyclerView.setAdapter(new FundsAdapter(mContext));
Here is the code sample how this FundsAdapter looks like.
public class FundsAdapter extends RecyclerView.Adapter<FundsAdapter.ItemHolder> {
private Context mContext;
public FundsAdapter(Context context) {
mContext = context;
}
#Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_funds_item, parent, false);
return new FundsAdapter.ItemHolder(view);
}
#Override
public void onBindViewHolder(ItemHolder holder, int position) {
}
#Override
public int getItemCount() {
return 10;
}
public class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView vh_Title;
private TextView vh_FundName;
public ItemHolder(View itemView) {
super(itemView);
vh_Title = (TextView) itemView.findViewById(R.id.txt_fund_bank);
vh_FundName = (TextView) itemView.findViewById(R.id.txt_fund_name);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
mContext.startActivity(new Intent(mContext, FundsDetailActivity.class));
}
}
}
Hope you got your solution. :)
I am using ControlFx PropertySheet in my project . I manage To get it running.
BeansObj:
public class BeansObj implements Serializable {
private String name;
private String mail;
private boolean smart;
private int age;
//Getters,Setters, Beans stuff....
}
ControllerClass:
public class Controller implements Initializable {
#FXML
private PropertySheet sheet;
#Override
public void initialize(URL location, ResourceBundle resources){
sheet.getItems().addAll(BeanPropertyUtils
.getProperties(new BeansObj("foo","foo#bar.foo",true,41)));
}
}
For the boolen field, the generated control is a checkbox with an empty text;
1-How to set this text value implicitly?
For the mail field(String)
2-how to add custom validation method?
For each field
3-how to add a css class|id to specific Control?
By default(I guess) all the controls belong to the Basic Category( PropertySheet.Mode)
4-how to set the category implicitly or explicitly ?
and, in case BeansObj has an Collection attribute
5-how to make it generate a tableView?
Thank you in advance.
How could i refresh Fragment/s content onBack Press ?
FragmentManager back = getFragmentManager();
back.beginTransaction().replace(R.id.left, new ArticleFragment()).commit();
back.beginTransaction().replace(R.id.middle, new LocationFragment()).commit();
refresh the contents of a fragment,
you could keep a reference to the fragment, and call a public refresh() method in that fragment.
when you create the tab fragment,
like the PupulareFragment, use the pupulareFragment instance variable to store the fragment. So it is available in the refresh button onClick method.
This way you are not replacing/creating any new fragments when refreshing. So going back to tabActivity after going to de article details activity, would probably work fine aswell.
Example:
public class ArticleTabFragmentActivity extends FragmentActivity{
private PopulareFragment populareFragment;
private RecomandateFragment recomandateFragment;
<the code...>
private void bindView(){
Button btn_refresh = (Button) findViewById(R.id.btn_refresh);
btn_refresh.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String current_tab = mTabHost.getCurrentTabTag();
if(current_tab.contains("POPULARE")){
populareFragment.refresh();
}
else if(current_tab.contains("RECOMANDATE")){
recomandateFragment.refresh();
}
});
}
}
public class PopulareFragment extends Fragment{
public void refresh(){
<refresh the contents of the fragment>
}
}