I am trying to implement action bar tabs and during which i am facing an error in implementing the fragment class.
public class fragmentImplement extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.fragment_layout);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_layout, container, false);
}
}
And XML file is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:id="#+id/textView1"
android:text="Fragment A"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
kindly help as i am getting very depressed
Please provide some more information (which error and where etc.) next time.
To use a Fragments you also need a FragmentActivity. A Fragment is a reusable component which you can use in a FragmentActivity.
Please use this tutorial as a starting point for using Fragments then go one step further and take a look into this article.
As far as I remember there is also an example in the Android SDK which has an ActionBar with tabs.
Related
so i'm creating an android app using Xamarin.android and i'm using the navigation drawer app. I added a fragment and within the fragment I added a button. now I need to handle some events of this button. I tried adding a click event function in the fragment.cs code but I got an exception "System.NullReferenceException: 'Object reference not set to an instance of an object.'". how am I supposed to handle the event?
this is the code of my main activity where I access my fragment when choosing the camera icon option:
Fragment1 fragment = new Fragment1();
public bool OnNavigationItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.nav_camera)
{
SupportFragmentManager.BeginTransaction()
.Replace(Resource.Id.mainFrame, fragment )
.Commit();
}
and this is my fragment's xml code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="hi"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="#+id/textView1" />
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/button1" />
</LinearLayout>
and this is my fragment's c# code where I try to access the button:
public class Fragment1 : Android.Support.V4.App.Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
base.OnCreate(savedInstanceState);
var view = inflater.Inflate(Resource.Layout.fragment1, container, false);
Button bulogin = View.FindViewById<Button>(Resource.Id.button1);
bulogin.Click += Bulogin_Click;
// return base.OnCreateView(inflater, container, savedInstanceState);
return view;
}
private void Bulogin_Click(object sender, EventArgs e)
{
TextView txt = View.FindViewById<TextView>(Resource.Id.textView1);
txt.Text = "bye";
}
}
I have a PreferenceActivity with a custom layout to keep a static header on top of all the items. I followed this thread to set this up:
Adding a header to a PreferenceActivity
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/myCustomImageView"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:src="#mipmap/ic_launcher" />
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/myCustomImageView" />
</RelativeLayout>
and here is my Activity snippet:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this makes a static header
setContentView(R.layout.preferences_layout);
// register as a listener
PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
yet, when I tap on an item it should spawn a fragment as my xml specifies:
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="ui.UserPreferences"
android:summary="#string/preferences_activity_user_settings_summary"
android:title="#string/preferences_activity_user_settings_title" />
more items....
However, it does not. Instead, it crashes saying:
java.lang.IllegalArgumentException: No view found for id 0x1020463 (android:id/prefs) for fragment UserPreferences
I looked at a bunch of threads like the one below, but they did not help.
Android PreferenceFragment No view found for id for fragment
However if I just commented out the custom layout, the code works and the fragment shows up correctly. This works, in other words:
public class Preferences extends PreferenceActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this works: By commenting out the custom header, the exception goes away
//setContentView(R.layout.preferences_layout);
// register as a listener
PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this);
}
I believe the fragment manager is not able to find the id because the listview is now nested inside a relativelayout. Yet, I have no idea how to fix this.
here's a bit of item fragment, however I don't think this is the problem:
public class UserPreferences extends PreferenceFragment implements
Preference.OnPreferenceChangeListener,
Preference.OnPreferenceClickListener,
SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Load the preferences from an XML resource */
addPreferencesFromResource(R.xml.user_settings);
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
more stuff...
Any help is greatly appreciated.
thank you.
I am trying to implement the Model-View-ViewModel architectural pattern and XML data binding in my Android Java app. The code seems all correct as far as I can see, however I'm getting a blank screen when I run the app (not even the bottomNavigationView is showing). I am using a ViewModel to store/persist data for a fragment called AllTimeBestFragment. Specifically, AllTimeBestFragment is one of three fragments in a Viewpager-tabLayout.
Would appreciated any insight into what I'm doing wrong!
AllTimeBestFragment
public class AllTimeBestFragment extends Fragment {
private ImageViewCallback imageViewCallback;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(Constants.SkiCompanionDebug, "AllTimeBestFragment");
bindToViewModel();
return inflater.inflate(R.layout.fragment_all_time_best, container, false);
}
//imageview callback
#Override
public void setUserVisibleHint(boolean visible) {
super.setUserVisibleHint(visible);
imageViewCallback.setImage(R.drawable.all_time_best);
}
public void addCallback(ImageViewCallback imageViewCallback) {
this.imageViewCallback = imageViewCallback;
}
//binding the view (fragment) to the asoociated viewModel
public void bindToViewModel(){
FragmentAllTimeBestBinding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_all_time_best);
AllTimeBestViewModel viewModel = ViewModelProviders.of(this).get(AllTimeBestViewModel.class);
AllTimeStats allTimeStats = BCCDatabase.getInstance(getActivity()).getAllTimeStats();
viewModel.init(allTimeStats);
binding.setAllTimeBestViewModel(viewModel);
}
}
AllTimeBestViewModel
public class AllTimeBestViewModel extends ViewModel {
private AllTimeStats allTimeStats;
public void init(AllTimeStats allTimeStats) {
this.allTimeStats = allTimeStats;
}
public String getDurationTotal(){
return ""+allTimeStats.getDurationTotal();
}
}
fragment_all_time_best.xml
<data>
<variable
name="allTimeBestViewModel"
type="skicompanion.skicompanion.viewmodels.AllTimeBestViewModel" />
</data>
<ScrollView 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/track_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout 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="wrap_content"
android:orientation="vertical"
tools:context="skicompanion.skicompanion.fragments.AllTimeBestFragment">
<android.support.v7.widget.CardView
android:id="#+id/duration_cardview"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/duration_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{allTimeBestViewModel.durationTotal}"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="#+id/duration_total_tv"
app:layout_constraintStart_toStartOf="#+id/imageView2"
app:layout_constraintTop_toBottomOf="#+id/duration_total_tv" />
...
...
...
Gradle
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
I found the answer here: How to use data-binding with Fragment
I was binding the data as if I were dealing with an activity - I needed to bind it for a fragment instead. The trick was to use DataBindingUtil.inflate rather than DataBindingUtil.setContentView. Below is the correct code snippet:
public class AllTimeBestFragment extends Fragment {
private ImageViewCallback imageViewCallback;
private FragmentAllTimeBestBinding binding;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(Constants.SkiCompanionDebug, "AllTimeBestFragment");
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_all_time_best, container, false);
bindToViewModel();
return binding.getRoot();
}
//imageview callback
#Override
public void setUserVisibleHint(boolean visible) {
super.setUserVisibleHint(visible);
imageViewCallback.setImage(R.drawable.all_time_best);
}
public void addCallback(ImageViewCallback imageViewCallback) {
this.imageViewCallback = imageViewCallback;
}
//binding the view (fragment) to the asoociated viewModel
public void bindToViewModel(){
AllTimeBestViewModel viewModel = ViewModelProviders.of(this).get(AllTimeBestViewModel.class);
AllTimeStats allTimeStats = BCCDatabase.getInstance(getActivity()).getAllTimeStats();
viewModel.init(allTimeStats);
binding.setAllTimeBestViewModel(viewModel);
}
}
My aim is to access MainActivity's ProgressBar and TextView from a Fragment. However, I am getting the error below:
Attempt to invoke virtual method 'void
android.widget.ProgressBar.setVisibility(int)' on a null object
reference
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:orientation="vertical"
android:layout_gravity="center">
<ProgressBar
android:id="#+id/pbLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="center"
android:visibility="visible"/>
<TextView
android:id="#+id/tvLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="#dimen/dimension_8dp"
android:fontFamily="#font/robotomedium"
android:textSize="16sp"
android:visibility="visible"
android:text="#string/loading_text"/>
</LinearLayout>
SampleFragment.java
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragmentDataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_currency_list, container, false);
return Objects.requireNonNull(fragmentDataBinding).getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
mPbLoading = fragmentDataBinding.getRoot().findViewById(R.id.pbLoading);
mPbLoading.setVisibility(View.GONE);
}
Tampered with lots of posts, articles but couldn't achieve it. Thanks in advance.
Best,
Option 1
make progressbar static on activity
and then access from fragment like -
if(MainActivity.progressbar!=null){
MainActivity.progressbar.setVisibility(View.Gone);
//or whatever do you want
}
Option 2
((YourActivityClassName)getActivity()).yourPublicMethod();
I try to add a fragment to an activity and have already looked at the example from Martijn00.
My problem is, that the activity will be displayed but the fragment will not and in debugging mode, the debugger is not running into the fragment's method OnCreateView. So the attribute of the fragment will be used, but not the fragment. I see only my activity with the green background. I am sure I do something wrong, but after 6 hours I do give up and ask you guys for help :)
Fragment:
namespace TopDownTodoList.Mobile.Droid.Views.Fragments{
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
[Register("topdowntodolist.mobile.droid.views.fragments.TodoOverviewFragment")]
public class TodoOverviewFragment : MvxFragment<TodoOverviewViewModel>
{
protected int LayoutId => Resource.Layout.f_todo_overview_fragment;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
this.Init();
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return this.BindingInflate(this.LayoutId, null);
//return inflater.Inflate(this.LayoutId, container, false);
}
public virtual void Init() { }
}}
Activity:
namespace TopDownTodoList.Mobile.Droid.Views{
[Activity(Label = "MainView")]
public class MainView : MvvmCross.Droid.FullFragging.Views.MvxActivity<MainViewModel>
{
protected int LayoutId => Resource.Layout.main_view;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(this.LayoutId);
this.Init();
}
public virtual void Init(){}
}}
App.cs:
protected override void RegisterClasses()
{
RegisterAppStart<TodoOverviewViewModel>();
}
ViewModels:
public class VMName : MvvmCross.Core.ViewModels.MvxViewModel{...}
FragmentLayout (f_todo_overview_fragment):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mvx="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#0000aa"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:gravity="center"/></LinearLayout>
ActivityLayout (main_view):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#aa0000"
android:layout_width="fill_parent"
android:layout_height="fill_parent"><FrameLayout
android:id="#+id/content_frame"
android:background="#00bb00"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" /></LinearLayout>
Your Activity needs to be of the type MvxCachingFragmentCompatActivity or MvxCachingFragmentActivity to support hosting of fragments.
Secondly you need to ignore the normal inflator, and use binding inflate after that:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
return this.BindingInflate(FragmentId, null);
}