ViewPager fragments, not attached? - android

I have a problem with ViewPager. It won't display any of my pre-definied fragments, it just displays a black screen. The onCreateView method is called from inside the fragments.
public class TestViewPager extends FragmentActivity {
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.test_view_pager);
}
}
public class TestFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.entry_layout, container, false);
return fragmentView;
}
}
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment
class="com.test.TestFragment"
android:id="#+id/embedded1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<fragment
class="com.test.AnotherTestfragment"
android:id="#+id/embedded2"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.view.ViewPager>

With ViewPager you must implement a PagerAdapter and supply the fragments from there. You can not define views/fragments to be shown in the ViewPager from XML, as it will simply not draw them.
Edit: Since you want to show Fragments, you must use FragmentPagerAdapter.

Related

List of fragment in android

I know that to show a list of views I can use recycler view with but what if I wanna reuse also my fragment logic too?
for example, if I have a fragment like this
XML
<androidx.constraintlayout.widget.ConstraintLayout 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=".views.fragments.testview">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="hi"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment class
public class TestView extends Fragment {
private TextView txt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.test, container, false);
initComponent(v);
return v;
}
private void hardTask1(){};
private void hardTask2(){};
//Some other hardtask
}
What I could do if I need to display a list of fragments in some activity but I don't want to rewrite all my TestView in the adapter?

Fragment is not showing up in activity

Trying to add Fragment to my Activity, but it isn't showing up.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherFragment mainFragment = new WeatherFragment();
getFragmentManager()
.beginTransaction()
.add(R.id.main_weather_container, mainFragment)
.commit();
}
}
And there is my fragment:
public class WeatherFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
boolean isAttachedToParent = false;
View inflatedView = inflater.inflate(R.layout.main_weather_fragment, container, isAttachedToParent);
return inflatedView;
}
}
R.id.main_weather_container - FrameLayout in my MainActivity.
R.layout.main_weather_fragment - Fragment's layout
What am i doing wrong?
I've tried to use FragmentActivity + v4 support fragment and fragmentSupportManager, but it didn't make any difference.
MainActivity xml:
<?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="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="#+id/main_weather_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="#dimen/padding_16_dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/words_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3" />
</LinearLayout>
UPDATED: The problem wasn't in fragment transaction or whatever, i've used tools: namespace that's why fragment wasn't displayed. Sorry about that :(
try this way .in your activity call fragment
Fragment fragment = Video_fragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.framecontainer, fragment).commit();
in fragment class.
public class Video_fragment extends Fragment{
View view;
public static Fragment newInstance() {
Video_fragment fragment = new Video_fragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view= inflater.inflate(R.layout.video_frag, container, false);
return view;
}
}
Create a instance of Fragment in WeatherFragment:
public static WeatherFragment newInstance() {
Bundle args = new Bundle();
WeatherFragment weatherFragment = new WeatherFragment();
weatherFragment.setArguments(args);
return weatherFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}
Inside your Activity in MainActivity :
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WeatherFragment weatherFragment = WeatherFragment.newInstance();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.flContainerId, weatherFragment)
.commit();
}
Your layout file will be:
<?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"
android:id="#+id/flContainerId"/>
public class WeatherFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View inflatedView = inflater.inflate(R.layout.main_weather_fragment, null, false);
return inflatedView;
}
}
As I can see, you are using AppCompatActivity but using getFragmentManager.
With AppCompatActivity you will need to use getSupportFragmentManager() rather than getFragmentManager()
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherFragment mainFragment = new WeatherFragment();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_weather_container, mainFragment)
.commit();
}
}
Your WeatherFragment should be extend android.support.v4.app.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="match_parent"
android:weightSum="4"
android:orientation="vertical">
<FrameLayout
android:id="#+id/main_weather_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="#dimen/padding_16_dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/words_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3" />
</LinearLayout>
Added WeightSum in the parent Layout.

Adding scrolllistener to a recyclerview and hide a view on another layout

I have some fragments let's say A, B, and C. I get the corresponding layouts for these fragments using inflate method.
In A and B, I have a Recycler View which I tend to add a Scroll Listener. Also, in fragment C, I have a view (let's say a tablayout) which I want to hide/show it by scrolling the recycler views (which are in A and B).
I am not sure how can I achieve that. Since the tablayout is in the layout of fragment C (and not in A and B).
I was trying to inflate the layout of C in A and B, but it didn't work.
This is the scrolllistener on recycler view (fragments A and B):
View view = inflater.inflate(R.layout.fragment_A, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.myChannelsRecyclerView);
tabLayout = (SmartTabLayout) view.findViewById(R.id.tabs);
recyclerView.addOnScrollListener(new HideShowScrollListener() {
#Override
public void onHide() {
//tabLayout.animate().translationY(250);
//tabLayout return null
}
#Override
public void onShow() {
//tabLayout.animate().translationY(0);
//tabLayout return null again
}
});
I should note that HideShowScrollListener() is a helper method which is written by me.
fragment_A.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">
<android.support.v7.widget.RecyclerView
android:id="#+id/myChannelsRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible" />
</RelativeLayout>
main_fragment.xml (fragment C)
<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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<come.example.CustomViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<smartertablayout.SmartTabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:stl_dividerThickness="1dp"
app:stl_defaultTabTextSize="9sp"
app:stl_distributeEvenly="true"
app:stl_indicatorThickness="0dp"/>
</LinearLayout>
Main fragment (fragment C in example) is responsible to change and replace the other fragments (A and B) using a pager. It somehow is the parent of this fragments
//something like this from my suggestion above
class Fragment_A extends Fragemnt{
YourScollListener animateCallback;
RecyclerView recyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_A, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.myChannelsRecyclerView);
recyclerView.addOnScrollListener(new HideShowScrollListener() {
#Override
public void onHide() {
animateCallback.animate();
}
#Override
public void onShow() {
}
});
return view;
}
public void onAttach(Context context) {
super.onAttach(context);
animateCallback = (YourScrollListener) getParentFragment();
}
public interface YourScrollListener{
void animate();
}
}
//main frag
class Main_Fragment extends Fragemnt implements YourScrollListener{
animate(){
//do stuff
}
}

How to launch another fragment in the current tab

I use below code to implement tabhost:
public class MyActivity extends FragmentActivity {
private FragmentTabHost mTabHost = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mylayout);
mTabHost = (FragmentTabHost) findViewById(R.id.tabHost);
mTabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(mTabHost.newTabSpec("A").setIndicator("A"), AFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("B").setIndicator("B"), BFragment.class, null);
}
}
It contains 2 tabs,
AFragment.class as below:
public class AFragment extends Fragment {
private MyAdapter MyAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_folder_base, container, false);
ListView ListV = (ListView)view.findViewById(R.id.listview);
FolderList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//How to implement to launnch another fragmentC under the same tab
}
});
...
MyAdapter = new MyAdapter(this.getActivity(), this.getContext());
ListV.setAdapter(MyAdapter);
return view;
}
}
I want to launch another fragment (FragmentC) when the item has been click, How can I implement it?
And how can I implement onBackPressed() function in these Fragments?
A: To add FragmentC in FragmentB, put this in FragmentB:
getActivity().getChildrenFragmentManager()
.beginTransaction()
.replace(R.id.fragmentCcontainer, new FragmentC)
.commit();
where the R.id.fragmentCcontainer is the id of the empty view placed on top of other fragmentB's views/ It is a fragment holder:
fragment_b.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Put FragmentB's Views Here-->
<FrameLayout
android:id="#+id/fragmentCcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
B: There is no onBackPressed() method in fragments. In your case, you should override activity's onBackPressed() method and implement the switch to previous tab in it;

Fragment.onCreateView has null container

The following is running on an Android 1.6 so I'm using the compatibility package for fragments. In the following TestFragment is a static nested class:
public class FragmentTestActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static class TestFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView result = new TextView(getActivity());
result.setText("Hello TestFragment");
return result;
}
}
}
The main.xml file:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<fragment class="com.test.FragmentTestActivity$TestFragment"
android:id="#+id/test"
android:layout_width="fill_parent" android:layout_height="fill_parent" />
</FrameLayout>
The strange thing is that the container parameter in onCreateView is null.
Now, if I add the fragment programatically like so(just change the onCreate method of the Activity) the container is no longer null. Why?
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fragment frag = new TestFragment();
getSupportFragmentManager().beginTransaction().add(android.R.id.content, frag).commit();
}
The documentation mentions that it can be null:
public View
onCreateView(LayoutInflater
inflater, ViewGroup container, Bundle savedInstanceState)
[...]
container: If non-null, this is the parent view that the
fragment's UI should be attached to. The fragment should not add the
view itself, but this can be used to generate the LayoutParams of the
view.
To be clear: you shouldn't do anything like container.addView(...).

Categories

Resources