We always have heard using multiple fragments with one activity. Is opposite possible? I am curious about this. Can we use same fragment for multiple activities. Please give ONE EXAMPLE.
How to reuse one Fragment in multiple Activities
The green background with two buttons is a single fragment that is reused among multiple activities.
1. Make your fragment class and layout
MyFragment.java
import android.support.v4.app.Fragment;
public class MyFragment extends Fragment implements View.OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myLayout = inflater.inflate(R.layout.my_fragment_layout, container, false);
// add click listeners to the buttons in the fragment
Button buttonOne = myLayout.findViewById(R.id.button_1);
Button buttonTwo = myLayout.findViewById(R.id.button_2);
buttonOne.setOnClickListener(this);
buttonTwo.setOnClickListener(this);
return myLayout;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_1:
Toast.makeText(getContext(), "Button One", Toast.LENGTH_SHORT).show();
break;
case R.id.button_2:
Toast.makeText(getContext(), "Button Two", Toast.LENGTH_SHORT).show();
break;
}
}
}
my_fragment_layout.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="#android:color/holo_green_dark"
android:orientation="vertical">
<Button
android:id="#+id/button_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"/>
<Button
android:id="#+id/button_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 2"/>
</LinearLayout>
2. Add the fragment to your activities
activity_blue.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"
android:background="#android:color/holo_blue_dark"
android:orientation="vertical">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="goToRedActivityButtonClick"
android:text="Go to red activity"/>
<!-- reused fragment -->
<fragment
android:id="#+id/my_fragment"
android:name="com.example.onefragmentmultipleactivities.MyFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
activity_red.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"
android:background="#ff3636"
android:orientation="vertical">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="goToYellowActivityButtonClick"
android:text="Go to yellow activity"/>
<!-- reused fragment -->
<fragment
android:id="#+id/my_fragment"
android:name="com.example.onefragmentmultipleactivities.MyFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
activity_yellow.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"
android:background="#f9f478"
android:orientation="vertical">
<!-- reused fragment -->
<fragment
android:id="#+id/my_fragment"
android:name="com.example.onefragmentmultipleactivities.MyFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
Notes
For simplicity we added the fragment directly to the xml. You can also load fragments dynamically in code. See the documentation for help with that.
Yes, it is possible to have one fragment with multiple activities.
But you will need to program the layout with java using LayoutParams and embed them in every fragment instance.
On every activity, you need to call this fragment
Create your UI Components in Java, add them to the layout dynamically from Java Class i.e. Your Activities.
I would suggest this approach will not be easy to maintain, if you are not super comfortable with Java exclusively. You will need to forget XML for this approach as nothing will be there in it at all, everything will be done with Java classes only.
generic_error_msg_fragment.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/White" >
<TextView
android:id="#+id/error_message_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center"
android:textColor="#android:color/darker_gray"
android:textSize="#dimen/font_size_16sp" />
<Button
android:id="#+id/error_button_handler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="left|center_vertical"
android:textSize="#dimen/font_size_16sp"
/>
</RelativeLayout>
GenericErrorFragment.Java
public class GenericErrorFragment extends Fragment{
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View genericView = inflater.inflate(R.layout.generic_error_msg_fragment, null);
TextView errorText = (TextView) genericView.findViewById(R.id.error_message_textview);
errorText.setText("error msg" );
Button errorbutton = (Button) genericView.findViewById(R.id.error_button_handler);
errorbutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// your logic launch some other activity
}
});
return genericView;
}
}
you can load this fragment in any activity and can define your custom text for error and button handler
I will not write whole code but I can give you exact example you are looking for
Think of an application in which a person can register either as admin or as user
Now while working on it you make 3 fragments in admin registration activity asking
1.) personal information
2.) academic information
3.) admin details
Now for user registration activity say you make 2 fragments to get the following information
1.) personal information
2.) user details
here you used personal information fragment 2 times for 2 activities
code for this is child's play main thing is the concept
Related
I create a Fragment, but I can't even move item.
If item is in the middle of my Fragment everything is correct, but if I try to add something that thing is invisible in my fragment.
Some pictures:
This is what I need
but I get something like that:
As you can see, button is different and if I try to move(button) it become invisible
Code
fragment_user_account_details.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"
android:background="#android:color/holo_green_light"
style="#style/Theme.Design.NoActionBar"
>
<Button
android:id="#+id/btnPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="78dp"
android:layout_marginEnd="74dp"
android:text="Pass"
android:textSize="30sp" />
<TextView
android:id="#+id/profileTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Profile Fragment"
android:textSize="30sp" />
</RelativeLayout>
UserAccountDetails class
public class UserAccountDetails extends Fragment
{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_user_account_details, container, false);
String bundle = getArguments().getString("UserDetails");
UserLogInData userLogInData = new Gson().fromJson(bundle, UserLogInData.class);
TextView txt = v.findViewById(R.id.profileTextView);
txt.setText(userLogInData.getUsername());
Button btnPass = v.findViewById(R.id.btnPassword);
btnPass.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View x) {
startActivity(new Intent(UserAccountDetails.this.getContext(), ChangePasswordPop.class));
}
});
return v;
}
}
I use this tutorial:
https://codinginflow.com/tutorials/android/navigation-drawer/part-3-fragments
Everything except name of my Class is the same.
Let me know if you need more info
The Root layout in your fragment is a Relative Layout, as the name suggests, this layout will set the position of the items either relative to itself or other child items in the layout,
If you want to move something then change its position with respect to another item in the RelativeLayout.
for example:
<?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:background="#android:color/holo_green_light"
style="#style/Theme.Design.NoActionBar">
<Button
android:layout_below="#+id/profileTextView"
android:id="#+id/btnPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="78dp"
android:layout_marginEnd="74dp"
android:text="Pass"
android:textSize="30sp" />
<TextView
android:id="#+id/profileTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Profile Fragment"
android:textSize="30sp" />
</RelativeLayout>
Here the button will move below the text, similarly you can make it go above
Relative Layout takes tags like android:layout_above="#id/yourID, android:layout_below='#id/yourID' and there are more tags to place your Buttons or TextViews you want to place with them as it is used to place things in relation to other layouts or Buttons and TextViews, etc.
How to let marquee text to show in every activity. Just write at one place and the marquee text should be reflect in every activity. How to do this..please help
here is one way to do that.
first create a BaseActivity that will be extended by every activity whose marquee is similar for every activity.
public abstract class BaseWaalaMarquee extends Activity {
FrameLayout flBaseActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_layout_marquee);
appendView();
}
private void appendView() {
flBaseActivity = (FrameLayout) findViewById(R.id.flBaseActivity);
View mainView = getLayoutInflater().inflate(getLayout(), null);
flBaseActivity.addView(mainView);
}
public abstract int getLayout();
}
create a base layout for this activity named base_layout_marquee as below
<?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">
<TextView
android:id="#+id/fact"
android:layout_width="200dp"
android:layout_height="40dip"
android:duplicateParentState="true"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="Loading... More text to see if it spans or not and want more">
<requestFocus
android:duplicateParentState="true"
android:focusable="true"
android:focusableInTouchMode="true" />
</TextView>
<FrameLayout
android:id="#+id/flBaseActivity"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
now create your own layout for the activity like below
<?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="#f00f0f"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your custom Layout" />
</LinearLayout>
finally create you activity that extends BaseWaalaMarquee as below
package ram.materialnavigation.opengltravis;
import ram.materialnavigation.R;
/**
* Created by view9 on 12/16/15.
*/
public class ExtendedBaseActivity extends BaseWaalaMarquee {
#Override
public int getLayout() {
return R.layout.your_custom_layout;
}
}
Now invoke ExtendedBaseActivity and see the result.
I guess this will be quite helpful for you. cheers
Simple..Take a global string variable and change it accordingly and use it in all the activities.
I have a viewpager with a fragment that contains a button. Here is the onCreateView of the fragment.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment, container, false);
refreshButton = (Button) v.findViewById(R.id.refreshButton);
refreshButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
refreshButton_Click();
}
});
return v;
}
I can verify that refreshButton_Click is not being called when I click on the refreshButton (which is clearly visible). I am guessing that the fragment just isn't getting focus or that it isn't allowing child elements to have focus.
Here is the layout for the fragment:
<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"
tools:context="com.me.philip.firehydrant.FeedFragment"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffededed">
<TextView
android:id="#+id/headerTextView"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:gravity="center"
android:text="header"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:layout_margin="2dp"
android:text="refresh"
android:id="#+id/refreshButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"/>
</LinearLayout>
<ExpandableListView
android:id="#+id/postList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"></ExpandableListView>
</LinearLayout>
EDIT: I forgot to mention: the button doesn't do the usual blue lighting up that buttons do when they are clicked, so I'm pretty sure it isn't the setOnClickListener that isn't working, but rather that the button is unable to get focus
Well, I believe I solved it. I had the ViewPager nested inside a DrawerLayout. I guess the similarity of their swiping gestures make them unworkable together.
I am trying to display 6 rows inside a linear layout. I want to do this through fragments as the content will be dynamic and the number of rows will also be dynamic later on. I have the following code but only one row appears on the screen. I have SettingsActivity.java, settings.xml ThemeRowFragment,java and theme_row_layout.xml.
SettingsActivity.java
//imports
public class SettingsActivity extends FragmentActivity {
private int NUM_THEMES = 7;
ThemeRowFragment[] view_themes;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
view_themes = new ThemeRowFragment[NUM_THEMES];
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
for (int i = 0; i < view_themes.length; i++) {
view_themes[i] = new ThemeRowFragment(COLOR_MAP[i]);
fragmentTransaction.add(R.id.theme_linear_layout, view_themes[i],
"Row" + i);
}
fragmentTransaction.commit();
}
}
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="#+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
</LinearLayout>
ThemeRowFragment.java
public class ThemeRowFragment extends Fragment {
private int[] colors;
public ThemeRowFragment(int colors[]) {
super();
this.colors = colors;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.theme_row_layout, container,
false);
return view;
}
}
theme_row_layout.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="horizontal" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/pick_colors" >
</TextView>
</LinearLayout>
Fragments will inflate themselves into the View you add them to. So you really can't do it this way. So you need to have X empty containers, one for each fragment you are going to inflate. Add each fragment to the same container will actually layer them all on top of each other, sort of making them really hard to see and use when the screen renders.
Alternatives:
You could do something like the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="#+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
<FrameLayout android:id="#+id/fragment_container1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container3"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container4"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container5"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<!-- etc. -->
</LinearLayout>
Or just add each FrameLayout programatically via the LinearLayout's addView() with a unique ID for each FrameLayout.
LinearLayout layout = (LinearLayout)findViewById(R.id.linear);
FragmentTxn txn = getFragmentManager.beginTransaction();
int i = 1; // This seems really fragile though
for (Fragment f : fragments) {
FrameLayout frame = new FrameLayout(this);
frame.setId(i);
layout.addView(frame);
txn.add(i, f);
i++;
}
txn.commit();
Or the other way would be to just use a listView and add each row that way. Not using Fragments at all.
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
<ListView android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
then later on do something like this:
ListView view = (ListView)findViewById(R.id.listview);
view.setAdapter(new ArrayAdapter(items) { // items is a collection of objects you are representing
public View getView(int position, View view, ViewGroup parent) {
view = LayoutInflator.from(parent.getContext()).inflate(R.layout.theme_row_layout, parent, false);
// manipulate the view
return view;
});
You are creating a instance of ThemeRowFragment n number of times. The problem is you are creating this as an fragment and trying to add it dynamically. Since you instantiate the same Fragment i suggest you to use ListView and use a custom adapter and set CustomView and override the getView method of your adapter to adjust your views
I'm trying to make a swipeable screen that has menu buttons, e.g: order, search, etc. (Just imagine it is like your android homescreen). If the button is clicked, it will lead to other page and start activity.
The problem is, I can make the screen swipeable but I can't connect the button in my fragment to another java when it is clicked.
How to make this possible?
Here is my code:
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View tab2 = inflater.inflate(R.layout.tab_dua, container, false);
B_vStock = (Button) tab2.findViewById(R.id.BtnStock);
B_vStock.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent z= new Intent(Tab_Dua.this, View_Stock.class); ==> error on this
startActivity(z);
}
});
swipeable layout (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:gravity="center"
android:orientation="vertical" >
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center">
<TableRow
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginBottom="20dp"
android:layout_weight="20"
android:gravity="center">
<ImageButton
android:src="#drawable/ord"
android:id="#+id/img_up_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="30dp" />
<ImageButton
android:src="#drawable/stock"
android:id="#+id/BtnStock"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</TableRow>
</TableLayout>
</LinearLayout>
Intent z= new Intent(Tab_Dua.this, View_Stock.class);
Assuming Tab_Dua is a Fragment, you cannot do this, the constructor of Intent will not accept a Fragment, it takes a Context. You could do this :
Intent z= new Intent(Tab_Dua.this.getActivity(), View_Stock.class);