YouTube Player Inside Tabbed Activity - android

I'm creating an app with tabbed activity and I want to put YouTube player on third tab.
Currently I have this java code :
public class FragmentTutorial extends Fragment {
public FragmentTutorial() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tutorial, container, false);
}
}
and here's my XML :
<FrameLayout 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="com.example.examplecom.FragmentTutorial">
</FrameLayout>
my question is...
most tutorials out there try to use this extends statement :
public class FragmentTutorial extends YouTubeBaseActivity {
in my case, I still need Fragment as extends statement. My code won't run if it changed into YouTubeBaseActivity.
any idea how to have youtube player inside fragment, specially in tabbed activity like this?
thank you

Your FragmentTutorial should extend YouTubePlayerFragment.

Related

Instantiate a custom activity class with a ListView object from MainActivity

Unlike typical android projects starting with MainActivity with all the code of the layout object in it. This architecture requires me to have the initial code in a custom object. Here's a structure for better understanding.
java/MainActivity.java
java/User.java
layout/activity_main.xml
layout/user.xml
Now I also need a reference to User object within MainActivity and it looks like this.
public class MainActivity extends AppCompatActivity {
public Users users; // instantiate custom class and show
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
My User class looks like this.
public class User extends AppCompatActivity {
ListView userList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.user_list, container, false); // Inflate the layout for this fragment
userList = view.findViewById(R.id.userList);
return view;
}
}
layout/user.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="org.puremvc.java.demos.android.employeeadmin.view.components.UserList">
<ListView
android:id="#+id/userList"
android:layout_width="395dp"
android:layout_height="715dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
</FrameLayout>
So, in other words, MainActivity just acts like a stage doing nothing except just providing a reference to the Initial object. Now I do need MainActivity to be there, can't point User to be a launcher in the manifest. Responsibilities are to be taken care of by User class.
Question: How to instantiate CustomClass User and show.
Context: The MainActivity class has to be minimalistic and clean, no User related code (ListView), all logic lies in the custom class.
P.S. There can be lateral approaches, as long as I have a reference to user Object in MainActivity and it's displayed on launch, I'll accept the answer.
As per my understanding: there should be two approaches.
First, by using the Fragment inside your Activity. Write all initialize and data flow codes inside the fragment and just initialize and start the fragment from the Activity. So when the Activity will start, it will give all its tasks to the fragment with its Context and rest thing Fragment will do.
Like below:
public class MainActivity extends AppCompatActivity {
public Users users; // instantiate custom class and show
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//the fragment stuff
FragmentManager fm= getFragmentManager() //or get SupportFragmentManager when the Fragment comes from Support lib
FragmentTransaction ft= fm.beginTransaction();
Fragment fragment= new UserListFragment();
ft.add(R.id.fragment_container, fragment);
ft.commit();
}
}
OR, the second approach should by using Interface and communicate both Activity and the Custom Class (or you can call it Controller) with it.
Its nothing, but a simple MVC design pattern which I never recommend.
You can write one Interface like below:
public interface IController{
public void initialize(Activity activity, Bundle savedInstanceState);
public void engage();
public void disengage();
}
Then, make an instance of this Controller inside your Activity/BaseActivity and use like below:
public MainActivity(IController controller){
this.controller = controller;
}
Then call each callback methods from their appropriate place to make them work inside the Controller.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//give the priviledge of onCreate to initialize
controller.initialize(this, savedInstanceState);
}
Then in your Controller class, just write the same program which you supposed to write inside Activity:
public class Your_Controller implements IController {
#Override
public void initialize(Activity activity, Bundle savedInstanceState) {
//do super where needed
//make one class level Activity instance to work in other methods
act = activity;
//just initialize views like below
TextView tv = (TextView) activity.findViewById(R.id.abc);
}

Mvvmcross: framelayout doesn't show fragment after activity

So I have a problem with a fragment not showing inside a MvxCachingFragmentCompatActivity.
The pattern I use to get to the problem is as follows:
Register a activity.
Navigate to another activity that extends MvxCachingFragmentCompatActivity
Load the fragment using await _navigationService.Navigate<[TheFragmentViewModel]>();
Fragment loading is called but it doesn't show anything.
Fragment declaration:
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
[Register(nameof(FirstFragment))]
public class FirstFragment : MvxFragment<FirstViewModel>
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(Resource.Layout.FirstView, container, false);
return view;
}
}
Main activity: (nothing special I think)
[Activity(Label = "Fragment View")]
public class MainActivity : MvxCachingFragmentCompatActivity<MainViewModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.MainView);
}
}
Main viewmodel
public class MainViewModel : MvxViewModel
{
private readonly IMvxNavigationService _navigationService;
public MainViewModel(IMvxNavigationService navigationService)
{
_navigationService = navigationService;
Init();
}
public async void Init()
{
await _navigationService.Navigate<FirstViewModel>();
}
}
Main activity layout: (very simple layout)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I also added a sample on github: Github link.
I also added a bug report on the Mvvmcross github, but I am not sure if it is a bug on my part or theirs?
You should never use async void or start an async task from a non async command. These are the first problems. Also your Initialize is not called because you are not using RegisterNavigationServiceAppStart<>(). Another thing is that you are supposed to navigate directly to a fragment and not first to the activity, because MvvmCross will handle that.
Another hint will be to use Dependency injection to resolve IMvxNavigationService.

Appcompat activity required as argument for function used in fragment

I am using an external library in my app. The first argument used in the example is "this". Which refers to an appcompat activity. However I am using this in a fragment shich obviously doesn't extend appcompat activity.
This is the library:
https://github.com/TouchBoarder/weekdays-buttons-bar
I am not sure whether there is anything I can do. Can I extend the fragment to something compatible (right now it just extends fragment).
Below is a screenshot of the issue:
EDIT:
This is what I extend in my MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
The Fragment that is called innside Main activity is extended like this:
public class AddAlarmFragment extends Fragment {
And I am trying to create the data source in the oncreate method of the fragment like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_add_alarm, container, false);
WeekdaysDataSource wds = new WeekdaysDataSource(, R.id.weekdays_stub)
.start(this);
new WeekdaysDataSource.Callback() {
#Override
public void onWeekdaysItemClicked(int attachId,WeekdaysDataItem item) {
// Do something if today is selected?
Calendar calendar = Calendar.getInstance();
if(item.getCalendarDayId()==calendar.get(Calendar.DAY_OF_WEEK)&&item.isSelected())
Toast.makeText(getActivity(),"Carpe diem",Toast.LENGTH_SHORT).show();
}
#Override
public void onWeekdaysSelected(int attachId,ArrayList<WeekdaysDataItem> items) {
//Filter on the attached id if there is multiple weekdays data sources
if(attachId==R.id.weekdays_stub){
// Do something on week 4?
}
}
};
Thanks in advance for your help.
Have you tried casting getActivity()?
((AppCompatActivity) getActivity(), R.id.weekdays_stub)
Read the Android API, you can see AppCompatActivity does extend FragmentActivity and getActivity() does return a FragmentActivity, not an AppCompatActivity, as expected by your library.
I do find it odd that a AppCompatActivity is even the defined parameter rather than a Context

Android fragments: container variable in onCreateView is null

i have an application that is only fragment based, and actually (i'm just creating basic content) i have only one fragment, declared directly into the layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:name="com.italialinux.fragments.MainFragment"
android:id="#+id/main_screen_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
/>
</FrameLayout>
And this layout is loaded inside main activity, with the following code:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_screen);
}
}
And the MainFragment class is the following:
public class MainFragment extends Fragment {
final static private long ONE_SECOND = 1000;
final static private long TWENTY_SECONDS = ONE_SECOND * 20;
private final static String TAG = "MainFragment";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
View view = inflater.inflate(R.layout.new_reminder, container, false);
return view;
}
And the new_reminder layout contains just two EditText and several labels.
The problem is that i cannot inflate the layout, since the container variable passed in onCreateView is null.
I saw many questions on SO, like the following:
Android Fragment is given a null container in onCreateView()
And all says that i need to use a transaction, but what i don't understood is:
if i have a fragment that is immutable, in a layout, and doesn't need to change (like in that case, and like in many examples where you have a ListFragment that contains a list of items), how i can inflate the layout inside the current view?
With ListFragment it works, but what if i don't want to use it?
The onCreateView method is called correctly.
In your main layout, try using android:layout_width="match_parent" instead of android:layout_width="0dp".
And you shouldn't be calling onSaveInstanceState(savedInstanceState) in onCreate; it is called by the framework when your fragment is going down to allow it to save its state.

findViewById returns NULL when using Fragment

I'm new to Android developing and of course on Fragments.
I want to access the controls of my fragment in main activity but 'findViewById' returns null.
without fragment the code works fine.
Here's part of my code:
The fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="HardcodedText" >
<EditText
android:id="#+id/txtXML"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:ems="10"
android:scrollbars="vertical">
</EditText>
</LinearLayout>
the onCreate of MainActivity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.initialisePaging();
EditText txtXML = (EditText) findViewById(R.id.txtXML);}
on this point the txtXML is null.
What's Missing in my code or what should I do?
Try like this on your fragments on onCreateView
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
LinearLayout ll = (LinearLayout )inflater.inflate(R.layout.tab_frag1_layout, container, false);
EditText txtXML = (EditText) ll.findViewById(R.id.txtXML);
return ll;
}
You should inflate the layout of the fragment on onCreateView method of the Fragment then you can simply access it's elements with findViewById on your Activity.
In this Example my fragment layout is a LinearLayout so I Cast the inflate result to LinearLayout.
public class FrgResults extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//some code
LinearLayout ll = (LinearLayout)inflater.inflate(R.layout.frg_result, container, false);
//some code
return ll;
}
}
I'm late, but for anyone else having this issue. You should be inflating your view in the onCreateView method. Then override the onCreateActivity method and you can use getView().findViewById there.
#Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment, container, false);
}
You can't access the the view of fragment in activity class by findViewById instead what you can do is...
You must have an object of Fragment class in you activity file, right? create getter method of EditText class in that fragment class and access that method in your activity.
create a call back in Fragment class on the event where you need the Edittext obj.
1) Try this:
Eclipse menu -> Project -> Clean...
update
2) If you have 2 or more instances of 'main' layout, check if all of them have a view with 'txtXML' id
3)
A Fragment is a piece of an application's user interface or behavior that can be placed in an Activity. Interaction with fragments is done through FragmentManager, which can be obtained via Activity.getFragmentManager() and Fragment.getFragmentManager().
The Fragment class can be used many ways to achieve a wide variety of results. It is core, it represents a particular operation or interface that is running within a larger Activity. A Fragment is closely tied to the Activity it is in, and can not be used apart from one. Though Fragment defines its own lifecycle, that lifecycle is dependent on its activity: if the activity is stopped, no fragments inside of it can be started; when the activity is destroyed, all fragments will be destroyed.
Study this. you must use FragmentManager.
If you want use findViewById as you use at activities onCreate, you can simply put all in overrided method onActivityCreated.
All the answers above tell you how you should "return the layout" but don't exactly tell you how to reference the layout that was returned so I was unable to use any of the solutions given. I used a different approach to solve the problem. In the Fragment class that handles the fragment, got to the onViewCreated() class and create a context variable in it that saves the context of the parent activity (main activity in my case).
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Context fragmentContext = (MainActivity) view.getContext();
}
Once that is done, you can use the new context to access items on your fragment from inside the onViewCreated() method.
EditText editText = context.findViewById(R.id.textXML);

Categories

Resources