I want to change fragments depending on button click. (I have made two fragment classes called fragmentLeft and fragmentMiddle)
This is my MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
Fragment fr;
public void selectFrag(View view) {
if(view == findViewById(R.id.bigbutton_left)) {
fr = new fragmentLeft();
}else {
fr = new fragmentMiddle();
}
FragmentManager fm = getFragmentManager();
if (fm != null) {
// Perform the FragmentTransaction to load in the list tab content.
// Using FragmentTransaction#replace will destroy any Fragments
// currently inside R.id.fragment_content and add the new Fragment
// in its place.
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_place, fr);
ft.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
This is fragmentLeft.java
public class fragmentLeft extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
return inflater.inflate(
R.layout.fragmentleft, container, false);
}
}
the same is for fragmenttwo with the exception of the layout id passed to infater.inflate()
I have made two layout files two, with the correct names as well .
This is the definition of my fragment from my activity_main.xml
But I am unable to get the buttons to do anything. No transactions take place, and I am stuck with the first fragment.
After a bit of googling , I came to know that its not recommended that you use fragment in the layout, but some other type of layout, but I saw this example code http://examples.javacodegeeks.com/android/core/app/fragment/android-fragments-example/
that seems to work just fine.
what is the problem ?
::EDIT::
There is something really weird going on.
If I use this layout xml file for main Activity:
<?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" >
<Button
android:id="#+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Fragment No.1"
android:onClick="selectFrag" />
<Button
android:id="#+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="selectFrag"
android:text="Fragment No.2" />
<fragment
android:name="com.mainpackage.FragmentOne"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
The fragments change and behave as they are expected to.
But if I use this layout:
<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"
tools:context=".MainActivity" >
<Button
android:id="#+id/button2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignBaseline="#+id/bigbutton_middle"
android:layout_alignBottom="#+id/bigbutton_middle"
android:layout_marginLeft="7dp"
android:layout_toRightOf="#+id/bigbutton_middle"
android:background="#drawable/mainbutton_right" />
<Button
android:id="#+id/bigbutton_left"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignBaseline="#+id/bigbutton_middle"
android:layout_alignBottom="#+id/bigbutton_middle"
android:layout_marginRight="7dp"
android:layout_toLeftOf="#+id/bigbutton_middle"
android:background="#drawable/mainbutton_left" />
<Button
android:id="#+id/bigbutton_middle"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="187dp"
android:background="#drawable/mainbutton_middle" />
<fragment
android:id="#+id/fragment_place"
android:name="com.mainpackage.FragmentOne"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_below="#+id/bigbutton_right" />
</RelativeLayout>
The fragments dont seem to change,i.e. the buttons seem to be dead.
What could be the problem ?
I am using Eclipse Juno
You are not getting a reference of the Buttons you are clicking in order for the FragmentTransaction to take place. You need to set OnClickListeners on the Buttons so they can execute relevant code.
One reason why the second layout doesn't display is because you are referencing an inexistant id:
<fragment
android:id="#+id/fragment_place"
android:name="com.mainpackage.FragmentOne"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_below="#+id/bigbutton_right" />
I do not see a View with an id of bigButton_right on that xml.
Another reason why the first xml works and the second doesn't is because you are not setting an onClick: property to any Button on the second xml.
Related
I have looked for several times, but I think no one is facing the same issue that I'm facing right now. I have the following fragment:
FRAGMENT XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="8dp"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</RelativeLayout>
RecyclerView XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
/>
</LinearLayout>
FRAGMENT JAVA CODE SNIPPET
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View viewRoot = inflater.inflate(R.layout.fragment_xml, container, false);
recyclerView = (RecyclerView) viewRoot.findViewById(R.id.recyclerview_id);
recyclerView.setOnTouchListener(new OnSwipeTouchListener(getActivity()) {
#Override
public void onSwipeRight() {
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
ft.replace(R.id.frameLayout, new Fragment2()).commit();
}
});
So, what I'm doing on the code above is adding a touch listener, so when the user swipe from right to left, the fragment goes to the other fragment (Fragment2)
This works perfectly fine! However... I need to add onClickListener inside my recyclerAdapter, so I can catch the click listener of each item. And here comes the problem... When adding a click listener, the swipe listener does not work. It seems that the listener of the click "overrides" my listener of the swipe. The question is. How to add both on the recyclerview, and make them work together?
I have fullscreen fragment dialog. While it is showing, background objects can be clickable or interact with user. how do i avoid this?
Here is piece of code how i show dialog:
MainActivity.java
FullScreenFrDialog fr = new FullScreenFrDialog();
FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
tr.add(android.R.id.content, fr, FR_TAG).commit();
FullScreenFrDialog.java
public class FullScreenFrDialog extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog, container, false);
return view;
}
}
dialog.xml
<?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:background="#CCFFFFFF" >
<ImageView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</FrameLayout>
main_activity.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" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
This button clickable, while dialog is showing.
Thanks in advance.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="#CCFFFFFF" >
Make the parents clickable true, hope this will help you.
In your onCreate() simply call setCancelable(false). This will prevent the dialog from closing if tapped outside the dialog and will also prevent tap events to the elements beneath
EDIT
Alternatively you can call setCanceledOnTouchOutside(false) if you want it to be dismissed with a back button press but still prevent touches to elements beneath
I've got this Layout:
ComposeView http://img845.imageshack.us/img845/2121/d6zp.png
The 2 borders (left,right )are filled by icons. When I touch one of these icons I access to other activity. The top black bar is a custom title bar.
The clear grey inside space is where I need to fit all activities that I've got on my app. So this layout would be something like a menu layout that would be static in all the activities.
This is the Layout xml:
menu_view.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"
tools:context="com.example.MenuView" >
<!-- Show top black custom title bar-->
<include
layout="#layout/custom_tittlebar" >
</include>
<!-- Button columns -->
<LinearLayout
android:id="#+id/lefthandmenu"
android:layout_width="85dip"
android:layout_height="match_parent"
android:layout_below="#id/title"
android:layout_alignParentLeft="true"
android:orientation="vertical"
android:background="#drawable/border_cut" >
<ImageView
... />
...
</LinearLayout>
<LinearLayout
android:id="#+id/righthandmenu"
android:layout_width="85dip"
android:layout_height="match_parent"
android:layout_below="#id/title"
android:layout_alignParentRight="true"
android:orientation="vertical"
android:background="#drawable/border_cut" >
<ImageView
... />
...
</LinearLayout>
<!-- Blank space which will contain other activities -->
<LinearLayout
android:id="#+id/activitycontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="#id/righthandmenu"
android:layout_toRightOf="#id/lefthandmenu"
android:layout_below="#id/title"
android:orientation="vertical" >
</LinearLayout>
And this is the class where are defined all the icon's onClickListeners.
MenuView.java
public class MenuView extends RelativeLayout {
private final LayoutInflater inflater;
Context context;
public MenuViewActivity(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.menu_view, this, true);
((ImageView)this.findViewById(R.id.navButton)).setOnClickListener(launch_nav);
}
final OnClickListener launch_nav = new OnClickListener() {
#Override
public void onClick(View v) {
getContext().startActivity(new Intent(getContext(), Navigation.class));
}
};
Well, having this (I'm not sure if its all ok, maybe I'm doing something wrong with the inflate method or something like this), now the thing would be to define the other activitie's layouts to be inside this view. To do this, I write:
ExampleActivity.java
public class ExampleActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout inside_menu_view = (LinearLayout)findViewById(R.id.activitycontent);
View this_layout = getLayoutInflater().inflate(R.layout.main, inside_menu_view, true);
inside_menu_view.addView(this_layout);
But I'm getting a NullPointerException on this last line. So, something when inflating on this snippets must be wrong.
Hey use the following structure. put. include your common layout in each and every activity 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" >
<!-- Show top black custom title bar-->
<include
android:id="#+id/ll_top"
layout="#layout/custom_tittlebar"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" >
</include>
<include
android:id="#+id/ll_left"
layout="#layout/custom_left"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" >
</include>
<include
android:id="#+id/ll_right"
layout="#layout/custom_right"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" >
</include>
<Button
android:id="#+id/btn_center"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="center"
android:layout_toRightOf="#+id/ll_left"
android:layout_centerHorizontal="true"
android:layout_below="#+id/ll_top"
></Button>
</RelativeLayout>
You can have one main activity like BaseActivity that is extended by FragmentActivity. Base activity extends SlidingFragmentActivity and implements basic structure like menu etc. FragmentActivity onCreate method is :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fm = getSupportFragmentManager();
//This is main content that is switchable
mContent = new MainListActivity();
//Additionally you can define those two lines as fragments and add them as default on both sides :
sideFragments = new sideFragments(this);
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, mContent);
ft.replace(R.id.side_framgments, sideFragments);
ft.commit();
}
When you press some of those buttons from your menu(left and right border) you will change the fragment in middle of the screen with this function in FragmentActivity :
public void switchContent(Fragment fragment, String tag) {
mContent = fragment;
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame,fragment).addToBackStack(tag).commit();
}
Note R.id.content_frame is the XML that is switchable between those two lines (let say menus on both sides) and R.id.side_framgments are those two lines in between the main layout that is switchable.
I'm starting to build a simple Android app so when I press my video button it calls a fragment which contains the video player, but I'm always getting: No view found for id 0x7f090005...
I wonder if you give me a hand by figuring out what is wrong in the code that I'm writing.
Here is my MainActivity.java file:
public class MainActivity extends Activity {
private Button mVideoButton;
Fragment fragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mVideoButton = (Button)findViewById(R.id.videoButton);
// Video Button
mVideoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
FragmentVideo sf = new FragmentVideo();
ft.add(R.id.fragmentVideo, sf);
ft.commit();
}
});
}
}
Then I have my main_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/activityStart" >
<ImageView
android:src="#drawable/armstrong_on_moon"
android:contentDescription="#string/description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:layout_weight="1" />
<TableRow
android:gravity="center|bottom"
android:layout_weight="0">
<Button
android:id="#+id/videoButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/video" />
</TableRow>
Next, my FragmentVideo.java class:
public class FragmentVideo extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState ){
View v = inflater.inflate(R.layout.fragment_video, parent, false);
return v;
}
}
And at last, the fragment_video.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/fragmentVideo" >
<VideoView
android:id="#+id/video"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />
<ProgressBar
android:id="#+id/prog"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="center" />
</LinearLayout>
Please let me know if I'm doing something wrong or if I'm missing something as I can see where the issue lays.
Thanks very much for any help in advance.
EGMWEB
On ft.add() the int parameter refers to the container to which you want to add the Fragment; you are trying to add the Fragment to the Fragment's own layout (Android doesn't find the View because it is not inflated yet, if it did it will throw and Exception in this case; you cannot add a Fragment to its own layout). You want to replace R.id.fragmentVideo with R.id.activityStart to add the Fragment to the current TableLayout that is part of the already inflated main_activity layout
Could you check whats the equivalent view for the id '0x7f090005' in the R.java file. It should be under gen folder of your project. The framework is not able to find this under the resource file that you have in this java class.
Good day. I have some problem.
I have app with listview at left and detail view at right. In right view I have a fragment with tab host. But I also want to add activities for all tabs.
For example:
I have clients list at left.
At right I have tabs: "clients comments", "clients photos", "clients Info"
In clients comments I need in activity with comments for this client, and with possibility to add new comment.
I have already made a list view and detail, but I have problems with integration tab hosts into it. So what I have. Here My code of detail fragment
public class ItemDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
DummyContent.DummyItem mItem;
private Activity lo_parentAct;
public ItemDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
if (mItem != null) {
Intent lv_intent;
// ((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.content);
TabHost tabHost=(TabHost)rootView.findViewById(R.id.tabHost);
tabHost.setup();
TabSpec spec1=tabHost.newTabSpec("Tab 1");
spec1.setIndicator("Общая информация");
lo_parentAct = this.getActivity();
lv_intent = new Intent(lo_parentAct, ClientInfoActivity.class);
TabSpec spec2=tabHost.newTabSpec("Tab 2");
spec2.setIndicator("Заметки");
lv_intent = new Intent(lo_parentAct, ClientCommentsActivity.class);
TabSpec spec3=tabHost.newTabSpec("Tab 3");
spec3.setIndicator("Фото");
lv_intent = new Intent(lo_parentAct, ClientPhotosActivity.class);
tabHost.addTab(spec1);
tabHost.addTab(spec2);
tabHost.addTab(spec3);
}
return rootView;
}
}
An the layout
<TabHost android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tabHost"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#android:id/tabs"
/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#android:id/tabcontent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/tab1"
android:orientation="vertical"
android:paddingTop="60px"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab1"
android:id="#+id/txt1"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tab2"
android:orientation="vertical"
android:paddingTop="60px"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 2"
android:id="#+id/txt2"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tab3"
android:orientation="vertical"
android:paddingTop="60px"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 3"
android:id="#+id/txt3"
/>
</LinearLayout>
</FrameLayout>
</TabHost>
add tab host with activities inside fragment
You can't put activities into fragments!
As I understand - you want to put TabActivity (wich is deprecated) with different activities into your main activity's root Fragment - this way is absolutely wrong.
One way to implement what you need is:
create one FragmentActivity.
put TabWidget into root layout of your FragmentActivity.
then put different Fragments into you TabWidget's tabs.
You can look at my similar answer with code examples into another theme (link).