try to use createFragment(). but android studio unable to recognize it. line #19. do i have to import something to use createFragment();
package com.example.simerpreetjassal.criminalintent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
/**
* Created by simerpreetjassal on 16-07-30.
*/
public class SingleFragmentActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment=fm.findFragmentById(R.id.framgment_container);
if(fragment==null){
fragment= createFragment();
fm.beginTransaction().add(R.id.framgment_container,fragment).commit();
}
}
}
similarly
android studio unable to recognize #override method named createFragment() method in following class. which is child of above class. Little frustrated.
package com.example.simerpreetjassal.criminalintent;
import android.support.v4.app.Fragment;
public class CrimeActivity extends SingleFragmentActivity {
#Override
protected Fragment createFragment(){
return new CrimeFragment();
}
}
Little idea here,
In Android there are two different methods to create fragment:
static method
dynamic method
Static method is when we “write” directly our fragment in XML file
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="horizontal" >
<fragment android:id="#+id/listFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
class="com.survivingwithandroid.fragment.LinkListFragment"
android:layout_weight="2"/>
</LinearLayout>
this case our layout isn’t dynamic because we can’t manage the fragment at runtime.
FrameLayout we can handle fragments as we need at runtime, but to do it we need a manager.
This is FragmentManager.
This component can
add
replace
remove fragments at runtime.
if we want to make our layout dynamic,we have to use FrameLayout.
private FrameLayout frameLayoutForFragment;
// i use this frame to do my transactions between fragments
frameLayoutForFragment = (FrameLayout) findViewById(R.id.frame);
GalleryFragment galleryFragment = new GalleryFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
frameLayoutForFragment.removeAllViews();
fragmentTransaction.replace(R.id.frame, galleryFragment).addToBackStack( "tag" );
fragmentTransaction.commit();
Note :
inside the transaction you can do above 3 things.
`android.support.v4.app.FragmentTransaction`
is used because your activity extends FragmentActivity
You miss the code which should be above onCreate method.
protected abstract Fragment createFragment();
U could check this code in the book 210p. The code is highlighted.
Related
I am learning Android from a couple of weeks.
I am now trying to use fragments. And using the ideas from https://github.com/dogriffiths/HeadFirstAndroid
from book
https://books.google.com/books?id=qkzrCQAAQBAJ&pg=PA275&lpg=PA275&dq=pure+java+class+fragments&source=bl&ots=Ayz-JbqS4r&sig=f2DBRNgX_wrvBnGrDhJiIfHNhrE&hl=en&sa=X&ved=0ahUKEwjD6OHS67rPAhUG1CYKHczIBnAQ6AEIMDAD#v=onepage&q=pure%20java%20class%20fragments&f=false
I am getting
'replace(int, android.app.fragment)' in
'android.app.fragmentTransaction' cannot be applied to
which is also
Error: ContactDetailFragment cannot be converted to Fragment
source code
import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
public class ContactActivity extends Activity implements ContactListFragment.ContactListListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
}
#Override
public void itemClicked(long id){
//method also defined in the listener
View fragmentContainer = findViewById(R.id.fragment_detail_container);
if (fragmentContainer != null){
ContactDetailsFragment detailsFragment = new ContactDetailsFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
detailsFragment.setContact(id);
//fragmentTransaction.replace(R.id.fragment_detail_container, detailsFragment);
fragmentTransaction.replace(R.id.fragment_detail_container, detailsFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.commit();
}
}
}
contactactivity.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:id="#+id/activity_contact"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:baselineAligned="false"
tools:context="esu.uco.rawal.p5rabina.ContactActivity">
<fragment
class="esu.uco.rawal.p5rabina.ContactListFragment"
android:layout_width="0dp"
android:layout_weight ="1"
android:layout_height="match_parent"
android:id="#+id/contact_list_frag"/>
<FrameLayout
android:id="#+id/fragment_detail_container"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
>
</FrameLayout>
</LinearLayout>
Check you imports. You may use wrong packages.
There are two Fragment classes:
Fragment
v4 Support Library
Fragment
as well as two FragmentTransaction classes:
FragmentTransaction
v4 Support Library FragmentTransaction
You can't use a v4 FragmentTransaction with a native Fragment or the opposite.
You may also want to read the Support Library Features docs.
Im working on a small google maps app that lets users find places close to them, I want to add functionality that lets the user add a place to a list of favourites, So far ive created classes that may do the functionality.
My main activity is my home page which opens other activities, code below:
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageButton;
public class MainActivity extends AppCompatActivity {
ImageButton btnNearBy;
ImageButton btnFavourites;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnNearBy = (ImageButton) findViewById(R.id.btnNearby);
btnNearBy.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent mapIntent = new Intent(getBaseContext(), MapsActivity.class);
startActivity(mapIntent);
}
});
btnFavourites = (ImageButton) findViewById(R.id.btnFavourites);
btnFavourites.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = MainActivity.this.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FavouriteListFragment fragment = new FavouriteListFragment();
fragmentTransaction.add(R.id.fragment_container, fragment); //ERROR ON THIS LINE
fragmentTransaction.commit();
}
});
}
}
Ive created a button that should open up the fragment that holds the list of favourites ,My fragment is declared like this:
public class FavouriteListFragment extends Fragment { ... }
Im a little unsure how to open the fragment from the MainActivity when clicking a button.
Any ideas?
Thanks!
There are two ways of displaying fragments:
1- First you need to define a fragment container in your code like the following:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="do something"
android:onClick="openFragment" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_height="wrap_content"
android:layout_width="match_content" />
</LinearLayout>
and then you need to create a function called openFragment in your activity and use the following code in openFragment:
getSupportFragmentManager().beginTransaction().add(R.id_fragment_container,new FavouriteListFragment()).commit();
2- You can define the fragment in your activity xml file like:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/my_fragment"
android:name="com.example.android.something.FavouriteListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.something.FavouriteListFragment"
tools:layout="#android:layout/fragment_layout" />
The first one is called dynamic fragment creation and the second one is called static. You have more freedom with the first one but if your fragment doesn't change throughout the activity it is simpler to use the second one
Since you are using android.support.v4.app.Fragment and there has been a lot of confusion in importing correct version. Try like this:
android.support.v4.app.FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FavouriteListFragment fragment = new FavouriteListFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Where fragment_container is FrameLayout inside activity_main.
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
Reference
I am using KitKat version to build an application which has a menu in the left and when you click in the option shows the fregment selected.
Now it is working but I wasn't clear the concept of the libraries, it is to say, I don't understand the differences using normal libraries and support v4.
Initially, I was using the standard library to set my fregment using
android.app.Activity
android.app.Fregment
and the code to add fregments:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
I decided to use support v4 in the activity because It wasn't working and the application stopped when I lanched it, myy code in the activity, and it is working is:
import android.support.v4.app.FragmentManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.FragmentActivity;
Fregment fragment = new MapaFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.frame_container, fragment);
...
ft.commit();
the code in fregment:
package info.android;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MapaFragment extends Fragment {
public PagesFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
return rootView;
}
}
The layour I use this layout (fragment_map.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
</LinearLayout>
What I would like to know it is the differences between the normnal libraries and support v4. I DON'T NEED EXAMPLES, I SET SOME EXAMPLES OF MY CODE I USED.
I need understand to apply everything in future right.
Could you help me please?
I would like to add multiple fragments in a single layout. However, I'm getting errors when I include additional fragments. Kindly assist.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="#F0F8FF"
android:id="#+id/my_layout">
<ExpandableListView
android:id="#+id/lvExp"
android:layout_width="250dp"
android:layout_height="match_parent" >
</ExpandableListView>
<fragment
android:id="#+id/fragw3"
android:name="com.example.engineercalclist2.arrayHistory"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
I hope i understood right, but here it goes:
Instead of adding Fragments directly from xml, you can use a FrameLayout. Then on your code ,lets say when you click on your ExpandableListView item, you can change the fragment. Here is a simple example.
Add this to your xml.
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
Now move on to your Activity, declara a Fragment
Fragment fragment = null;
Then on your OnItemClickListener for your ExpandableListView set the fragment to the fragment you want to change like this.
fragment = new Fragment_ToGo();
Then use this
FragmentTransaction ft = getFragmentManager().beginTransaction();
getFragmentManager().beginTransaction().commit();
ft.replace(R.id.content_frame, fragment);
ft.commit();
EDIT
Now, I'm going to use the tutorial from here. I suggest you to read there first, down below is my explanation.
First of all, if your API is older than 11 your MainActivity ,which contains Fragments, should be extended to FragmentActivity. If you are using API 11 or newer, you are good to go.
Now, create your Fragment(s) like this.
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class ArticleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.article_view, container, false);
}
}
This is going to be your Activity's XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="#+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.android.fragments.ArticleFragment"
android:id="#+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
And finally, your MainActivity:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
}
}
Now since i don't know what error do you get, I'm only able to help you to this point. I will edit my answer again when you post your Logcat.
I am trying to allow my app to call functions from my fragment classes in the fragmentactivity. However I am having a lot of issues just finding the fragment. Right now I can find one fragment by id which I think is the fragment hosting the tabs. But when I get the child fragment manager I get returned a null. Can anyone help?
This is the fragment activity
package com.example.profileactivity;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TabHost.TabSpec;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTabHost;
public class ProfileActivity extends FragmentActivity {
// Fragment TabHost as mTabHost
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this,getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("user").setIndicator("User",
getResources().getDrawable(R.drawable.ic_user_tab)),
UserProfileTab.class,null);
mTabHost.addTab(mTabHost.newTabSpec("payment").setIndicator("Payment",
getResources().getDrawable(R.drawable.ic_payment_tab)),
PaymentInfoTab.class,null);
}
public void buttonClick(View view){
FragmentManager fm = getSupportFragmentManager();
if(fm.findFragmentById(R.id.realtabcontent) == null){
Log.d("TABHOST", "didnt find fragment");
}
else{
Log.d("TABHOST", "found fragment");
//PaymentInfoTab paymentTab = (PaymentInfoTab)fm.findFragmentByTag("payment");
//paymentTab.boom();
if(fm.findFragmentById(R.id.realtabcontent).getChildFragmentManager().findFragmentByTag("payment") != null){
PaymentInfoTab paymentTab = (PaymentInfoTab)fm
.findFragmentById(R.id.realtabcontent)
.getChildFragmentManager()
.findFragmentByTag("payment");
paymentTab.boom();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.profile, menu);
return true;
}
}
This is the xml for the fragmentactivity.
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
Try using the tag on the activity's FragmentManager directly.
The complete reference of your example seems to be this. Follow this example with more details, you will see that the writer keeps track of tabs and their tag.
I had the similar issue with fetching fragments after tab change which always returned null. Posting Runnable at the end of TabHost message queue did the trick:
tabHost.post(new Runnable() {
#Override
public void run() {
Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(tag);
fragment.updateList(newList);
}
});