Change Fragment dynamic - android

I have 2 questions. First, can me say someone, why this not works? I just try to change the fragment, but he does nothing. I just see the first fragment.
mainActivity:
...
if (savedInstanceState == null) {
fm.beginTransaction()
.add(R.id.firstFragment, new firstFragment()).commit();
}
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
switchFragment(R.id.firstFragment, new firstFragment());
}
});
findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
switchFragment(R.id.secondFragment, new secondFragment());
}
});
}
private void switchFragment(int fragId, Fragment frag){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(fragId, frag);
ft.commit();
}
Fragments like this in the main.xml:
<Fragment
android:id="#+id/firstFragment"
android:name="com.example.firstFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/View01"
android:layout_below="#+id/view1" />
Fragmentclass just have this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_clublist, container, false);
return view;
}
And a Fragment just look like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#FFFF0000"/>
I don't know, why he does not change the fragment. A check, that switchFragment really calling is true.
Second question is: Is this a good way to change fragments? What is, if i have 10 fragments?
Thanks for your help! :)

int fragId
should be the id of the container that hosts the Fragment, not the id of the fragment itself

Related

I can not understand with the fragments and BackStack

I have aсivity with one button and frame:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="new fragment"
android:id="#+id/replaceFragment" android:layout_gravity="center_horizontal"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_gravity="center_horizontal" android:id="#+id/contentFrame">
</FrameLayout>
</LinearLayout>
code:
public class MyActivity extends Activity implements View.OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button replaceBtn = (Button) findViewById(R.id.replaceFragment);
replaceBtn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.replaceFragment:
Fragment fragment1 = new Frag1();
FragmentTransaction fTrans = getFragmentManager().beginTransaction();
fTrans.replace(R.id.contentFrame, fragment1);
fTrans.commit();
break;
}
}
}
button is pressed, etc. I create a fragment:
public class Frag1 extends Fragment implements View.OnClickListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag1, null);
Button replaceBtn2 = (Button) v.findViewById(R.id.replaceFragment2);
replaceBtn2.setOnClickListener(this);
return v;
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.replaceFragment2:
Frag2 fragment2 = new Frag2();
FragmentTransaction fTrans = getFragmentManager().beginTransaction();
fTrans.replace(R.id.contentFrame,fragment2);
fTrans.commit();
break;
}
}
}
it also has a button which when pressed I create fragment2:
public class Frag2 extends Fragment implements View.OnClickListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag2, null);
Button replaceBtn3 = (Button) v.findViewById(R.id.replaceFragment3);
replaceBtn3.setOnClickListener(this);
return v;
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.replaceFragment3:
Frag3 fragment3 = new Frag3();
FragmentTransaction fTrans = getFragmentManager().beginTransaction();
fTrans.replace(R.id.contentFrame,fragment3);
fTrans.commit();
break;
}
}
}
fragment2 also creates a new fragment3:
public class Frag3 extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag3, null);
return v;
}
}
if I do when creating each fragment will add a line:
fTrans.addToBackStack(null);
then later when I press the "back" button on the screen will appear the fragments in reverse order. but I want to when I'm in fragmente3 when you press the "back" appears immediately fragment1.
if I do not add the line fTrans.addToBackStack(null); in fragment2 they overlap.
in order to do that, you can keep the fragments backStack references in your activity or for example onBackPressed you could try something like below:
if (getSupportFragmentManager().getBackStackEntryCount() != 0) {
//back to fragment 1.
}
Here you are a function which I use for one of my projects. I implemented it in the parent of the Activity that manages the fragments. I don't know if I'm going to clarify anything about the behaviour because all you tell us in you question make sense to me.
I my case, it was a simple app (almost static), but it changes fragments and, as you want to, many times I want to go back two fragment in "history" so I think it could help.
#Override
public void replaceFragment(FRAGMENT_TYPE destinyFragmentType, int fragmentContainerID, boolean addToBackStack) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
Fragment currentFragment = FragmentFactory.getFragment(destinyFragmentType);
fragmentTransaction.replace(fragmentContainerID, currentFragment);
if (addToBackStack) {
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commit();
}
Notes:
The second parameter is the parameter that indicates if you want to
keep in history or not. For your case: frg1 -> fr2 : param true; fr2
-> fr3 : param false;
I used a Factory in order to get a cleaner code, but you can use
whatever you want, change the header, give the function your fragment
etc.
I hope this helps!!

Get edittext value from fragment

I am using fragments,I have an edittext in fragment and I want to get value in main activity.
This is my fragment layout
<?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"
android:orientation="vertical"
android:background="#878787" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="dfgdfgdf"
android:textSize="20dp"
android:layout_centerInParent="true"
android:id="#+id/user_name"/>
<EditText
android:id="#+id/message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:text="Gönder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="getFromUser"
android:layout_marginTop="40dp"
/>
</RelativeLayout>
I am loading fragment with this function:
public void startChat(JsonObject user) {
FrameLayout layout = (FrameLayout)findViewById(R.id.container);
layout.setVisibility(View.VISIBLE);
Bundle bundle = new Bundle();
bundle.putString("name", user.get("name").getAsString());
sendTo=user.get("username").getAsString();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ConversationFragment conv = new ConversationFragment();
conv.setArguments(bundle);
fragmentTransaction.add(R.id.container, conv);
fragmentTransaction.commit();
viewPager.setVisibility(View.GONE);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayHomeAsUpEnabled(true);
}
And this is my fragment class
public class ConversationFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String name = getArguments().getString("name");
View rootView = inflater.inflate(R.layout.fragment_conversation, container, false);
TextView username=(TextView)rootView.findViewById(R.id.user_name);
username.setText(name);
return rootView;
}
}
As you can see when press the button main activity runs "getFromUser" function.I want to get edittext value in this function.How can I do this ?
It's always the same procedure for these things. You can't access a fragment's views just like that. You need a callback method.
Add this code to ConversationFragment:
private OnGetFromUserClickListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnGetFromUserClickListener ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnGetFromUserClickListener");
}
}
public void getFromUser(View v) {
if (mListener != null) {
EditText edit = (EditText)findViewById(R.id.message);
mListener.getFromUser(edit.getText().toString());
}
}
public interface OnGetFromUserClickListener {
void getFromUser(String message);
}
Make your MainActivity implement this interface. Replace getFromUser() inside MainActivity with:
public void getFromUser(String message) {
sendMessage(message);
}
Done.
Edit:
Actually, using the XML-onClick attribute is currently bugged (see onClick inside fragment called on Activity): It links to the activity instead of the fragment. You have to set the click listener programmatically to make sure the code won't break at some point in the future. So give the button an ID inside the XML (e.g. get_from_user) and add this code to onCreateView inside ConversationFragment:
v.findViewById(R.id.get_from_user).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.getId() == R.id.get_from_user) {
getFromUser(v);
}
}
});
Using this code vastly decouples the activity and the fragment from each other.
I resolved this problem.
public void getFromUser(View view) {
ConversationFragment fragment1 = (ConversationFragment)getSupportFragmentManager().findFragmentById(R.id.container);
View frag=fragment1.getView();
EditText editText1 =(EditText) frag.findViewById(R.id.message);
String message=editText1.getText().toString();
sendMessage(message);
}
Now I can get edittext value from fragment.

Trying to learn fragments, why fragment is not showing up

Here is the xml for my main layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/fragment_placeholder"
android:layout_width="250dp"
android:layout_height="0dip"
android:layout_weight="1" >
<ImageView
android:contentDescription="image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</FrameLayout>
</LinearLayout>
Code for fragment class
public class ExerciseFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_layout, container, false);
return view;
}
}
and code in main activity for showing fragment on click of a button:
ExerciseFragment fragment = new ExerciseFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_placeholder, fragment);
ft.commit();
if (fragment.isVisible()) {
Toast.makeText(this, "works", Toast.LENGTH_LONG).show();
} else
Toast.makeText(this, "nooooo", Toast.LENGTH_LONG).show();
The toast says "noooo" meaning the fragment is not visible, and it still shows an image which i set up in the framelayout holder which i want to replace. Any ideas why the fragment is not showing up?
EDIT: COMPLETE CODE FOR MAIN ACTIVITY
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getActionBar().setDisplayHomeAsUpEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.workout_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_exercise:
ExerciseFragment fragment = new ExerciseFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_placeholder, fragment);
ft.commit();
if (fragment.isVisible()) {
Toast.makeText(this, "works", Toast.LENGTH_LONG).show();
} else
Toast.makeText(this, "nooooo", Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
Instead of using ft.replace(R.id.fragment_placeholder, fragment);, try using ft.add(R.id.fragment_placeholder, fragment);. Since the R.id.fragment_placeholder doesn't contain a fragment yet, you aren't replacing anything, you are merely adding on to the layout. The .add(int containerViewId, Fragment fragment) function should work for your case. In the future, if you are going to change the fragment contained in R.id.fragment_placeholder, use .replace(int containerViewId, Fragment fragment).
Hope this works!

Accessing Views inside fragment

I'm having troubles accessing the Views that within my Fragment. In the example below, I can't access the 2nd button that is within the Fragment (e.g., findViewById appears to return NULL and the app crashes when I try b2.setText("test") ), but when I directly add it in the activity_main.xml, it does work.
Here is the code:
MainActivity.java
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button fragmentButton = (Button)findViewById(R.id.iMainButton);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.iMainInnerLLContainer, new TestFragment());
ft.commit();
final Button b2 = (Button)findViewById(R.id.iTestFragmentInnerButton);
if(b2 == null) { Log.d("MainActivity.java:", "b2 is null"); }
else { Log.d("MainActivity.java:", "b2 is NOT null"); }
fragmentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// do stuff here
}
});
}
}
activity_main.xml
<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:id="#+id/iMainRootLinearLayoutContainer"
android:orientation="vertical"
>
<Button
android:id="#+id/iMainButton"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Add fragment..."
/>
<LinearLayout
android:id="#+id/iMainInnerLLContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
>
<!-- Fragment goes here, can reference button if it is added here manually -->
</LinearLayout>
</LinearLayout>
TestFragment.java
public class TestFragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.ltestfragment, container, false);
}
}
ltestfragment.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:orientation="vertical"
android:id="#+id/iTestFragmentOuterLinearLayout"
>
<Button
android:id="#+id/iTestFragmentInnerButton"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="This is my test fragment button."
/>
</LinearLayout>
I think I'm missing something very basic here and I would appreciate some insight on what that might be.
Thank you in advance!
I think you need to set up a textchangelistener in your fragment.
public class FragmentA extends Fragment {
TextChangeListener listener;
public interface TextChangeListener {
public void onTextChange(CharSequence newText);
}
public void setTextChangeListener(TextChangeListener listener) {
this.listener = listener;
}
Then, in your activity, set up the listener :
public class ActivityAB extends FragmentActivity {
FragmentA fragmentA;
FragmentB fragmentB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ab);
FragmentManager manager = getSupportFragmentManager();
fragmentA = (FragmentA) manager.findFragmentById(R.id.fragmentA);
fragmentB = (FragmentB) manager.findFragmentById(R.id.fragmentB);
fragmentA.setTextChangeListener(new TextChangeListener() {
#Override
public void onTextChange(CharSequence newText) {
fragmentB.updateTextValue(newText);
}
});
}
}
Implement an interface to listen to the events of a fragment from its activity.
Code in Fragment:-
public class TestFragment extends Fragment
{
public interface OnClickListener
{
public void onButtonClicked(<data type><data>);
}
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
listener.onButtonClicked(<<pass some values here>>);
}
});
}
Code in Main:-
MainActivity extends FragmentActivity implements TestFragment.OnClickListener,
{
#Override
public void onButtonClicked(<<receive the pased data here>>) {
//do some stuff here with the received data after the button is clicked
}
}

fragments in tabview

i am creating a tab view in that when a button is clicked it must move to another screen when i try to implement it using the above code it is changing to another screen but the button is still visible with next screen and i want next screen should cover entire screen
public class Tab1Fragment extends Fragment {
LinearLayout mLayout;
/** (non-Javadoc)
* #see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
*/
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
LinearLayout theLayout = (LinearLayout)inflater.inflate(R.layout.tab_frag1_layout, container, false);
// Register for the Button.OnClick event
Button b = (Button)theLayout.findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment mFragment = new third_fragment_view();
android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, mFragment);
ft.addToBackStack(null);
ft.commit();
}
});
return theLayout;
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#00bfff"
android:id="#+id/container1" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
The Ui to cover the entire Screen dn't use Fragments.Use Intents
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setClass(thisactivity.class,targetactivity.class);
startActivity(intent);
}
});

Categories

Resources