Open Fragment From Activity - android

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

Related

Default fragment in activity

I've seen many posts on this matter, but I can't figure it out for my code. I have created a tabbed activity and set three buttons at the bottom. The buttons switch between different fragments. A button in a MainActivity opens this tabbed activity, but the problem is that the fragment layout is empty (see image below).
The buttons work perfectly and send me to the right fragments, but when it opens, no fragments are loaded.
The code, which I build following an YouTube tutorial looks like this:
TabbedActivity.class
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
public class TabbedActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed_activity);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
int intentFragment = getIntent().getExtras().getInt("frgToLoad");
switch (item.getItemId()) {
case R.id.navigation_home:
transaction.replace(R.id.content,new Fragment_B1()).commit();
/* mTextMessage.setText(R.string.title_home);*/
return true;
case R.id.navigation_dashboard:
transaction.replace(R.id.content,new Fragment_B2()).commit();
/*mTextMessage.setText(R.string.title_dashboard);*/
return true;
case R.id.navigation_notifications:
transaction.replace(R.id.content,new Fragment_B3()).commit();
/*mTextMessage.setText(R.string.title_notifications);*/
return true;
}
return false;
}
};
}
The fragments have the same code pattern inside, which is basic and it makes no point to add it here. The xml of the TabbedActivity looks like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="TabbedActivity">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="#+id/appbar">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
Can anyone help me to figure out how to open Fragment_B1 by default? I have tried adding the code from the best answer from here, but still doesn't work.
You can just added the original fragment direct on the onCreate, like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed_activity);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
if(savedInstanceState == null) {
getSupportFragmentManager().
beginTransaction().replace(R.id.content,new Fragment_B1()).commit();
}
}
In the last add, navigation.setSelectedItemId(navigation_home);

Fragment button affecting other instances of the same fragment

I have a button that adds an instance of a fragment, ActivityFragment, when pressed. There is an edit_button in the fragment that, when pressed, changes the activity_text textview in the fragment. However, when multiple instances of ActivityFragment are added, any edit_button pressed in any fragment will only affect the first ActivityFragment added. I believe this is happening because each fragment shares the same id, but would there be any way to get around this so that each edit_button only affects the fragment that it is in, preferably without changing the fragment id upon creation?
Here is the Activity Fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="wrap_content"
android:id="#+id/activity_fragment">
<CheckBox
android:id="#+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/activity_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="Edit Activity"
android:textSize="18sp"
app:layout_constraintBaseline_toBaselineOf="#+id/checkbox"
app:layout_constraintLeft_toRightOf="#+id/checkbox"
app:layout_constraintRight_toLeftOf="#+id/edit_button"/>
<Button
android:id="#+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:onClick="editActivity"
android:text="Edit Activity"
app:layout_constraintBaseline_toBaselineOf="#+id/checkbox"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
Here is my MainActivity.java with the ActivityFragment class. The onClick method for the edit_button is at the very bottom:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public static class ActivityFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.activity_fragment, container,
false);
}
}
public void addActivity(View view) {
ActivityFragment fragment1 = new ActivityFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment1).commit();
}
//This is the editButton method
public void editActivity(View view) {
TextView activityText = (TextView) findViewById(R.id.activity_text);
activityText.setText("success");
}
}
*This is my first time posting a question, sorry if I'm doing anything incorrectly.
This is happening because you're adding lots of fragments to your view. You haven't noticed that because all of them are equals to each other. I think you have to change this:
public void addActivity(View view) {
ActivityFragment fragment1 = new ActivityFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment1).commit();
}
to this:
public void addActivity(View view) {
ActivityFragment fragment1 = new ActivityFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment1).commit();
}
You have to remember that, when you're adding, all the views are appended and the findViewById will find the first one. And you can remove the static from the Fragment.
By using this :
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment1).commit();
You are stacking up fragments one over the other. Change it to
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment1).commit();

How to fix fragmentTransaction.replace error and cannot be converted to Fragment

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.

is createFragment() method in android world?

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.

Fragment returned two views

i had impemented fragment in my project. I added an ImageButton in my fragment XML. But when i inflated it to my activity there is two buttons in my layout activity. Why my fragment returned two views? and how to fix it have to normal view like in my fragment XML? Thanks in advance.
screenshot
*I am sorry i can not upload image, my reputations is not enough
You can look at the picture, there is 2 buttons. I just want one button.
below is my activity.xml
<?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:background="#ffffff"
android:orientation="vertical"
android:padding="10dp" >
<fragment
android:id="#+id/fragment1"
android:name="com.candlelightstudio.letsbesmartkid.ToolbarAbout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg_pilihsoal"
android:orientation="vertical" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:cacheColorHint="#android:color/transparent" >
</ListView>
</LinearLayout>
</LinearLayout>
below is my fragment xml, named toolbar_about
<?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:background="#android:color/transparent"
android:orientation="vertical" >
<ImageButton
android:id="#+id/btn_ToolAbout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#android:color/transparent"
android:src="#android:drawable/ic_menu_info_details" />
</LinearLayout>
below is ToolbarAbout.java
package com.candlelightstudio.letsbesmartkid;
import android.os.Bundle;
import android.app.Fragment;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.support.v4.app.FragmentActivity;
import android.app.FragmentManager;
public class ToolbarAbout extends Fragment {
private FragmentAbout about;
private FragmentManager fm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.toolbar_about, container, false);
ImageButton tool = (ImageButton) v.findViewById(R.id.btn_ToolAbout);
final Context c = inflater.getContext();
about = new FragmentAbout();
fm = getFragmentManager();
tool.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
about.show(fm, "About");
}
});
return v;
}
}
below is piece of my activity.java for inflate the fragment
Fragment fr = new ToolbarAbout();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fr);
fragmentTransaction.commit();
SOLVED
Only delete the code for inflating fragment, and it's work properly
delete this code
Fragment fr = new ToolbarAbout();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fr);
fragmentTransaction.commit();
cause i have declare a class for my fragment, here :
<fragment
android:id="#+id/fragment1"
android:name="com.candlelightstudio.letsbesmartkid.ToolbarAbout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
you can see i added android:name="com.candlelightstudio.letsbesmartkid.ToolbarAbout"
Thanks a lot #Manpreet Singh
I guess the ToolbarAbout fragment will be inflated automatically in your app since you provided the following line in your xml :
android:name="com.candlelightstudio.letsbesmartkid.ToolbarAbout
so there is no need to replace fragment for this so remove these lines from activity :
Fragment fr = new ToolbarAbout();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fr);
fragmentTransaction.commit();
You add the fragment via code and xml. For example to do it through code only, you'd change the fragment view to a container:
<FrameLayout android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

Categories

Resources