So, I have a Search Criteria Fragment, where search criteria can be entered, and when the search is performed, the results of the search are shown in a Search Results Fragment. In landscape on a tablet, the two fragments naturally can be displayed side by side. This is straightforward to implement so far.
In portrait orientation, and on a phone, I'd like the Search Criteria fragment to be displayed like a popup dialog instead of beside the search results. In the Selecting Between Dialog or Embedding section of the DialogFragment, I see that I can either embed the fragment, or show it as a dialog. This might work for me if it weren't complicated by orientation changes.
If I am using <fragment> XML tags in the layout for the activity, I get into all sorts of trouble when I make orientation changes.
EDIT: Today I decided to try and see if I could get a simple workflow using a DialogFragment toggling between showing a dialog and embedded depending on the orientation of the device. This turns out to be quite difficult, and I still haven't found something that works. Here's what I have so far.
package org.nsdev.experiments;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class FragmentSearchTestActivity extends FragmentActivity
{
private static SearchCriteriaFragment searchCriteriaFragment;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View container = findViewById(R.id.search_criteria_container);
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (searchCriteriaFragment == null)
{
searchCriteriaFragment = SearchCriteriaFragment.newInstance();
searchCriteriaFragment.setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}
android.support.v4.app.Fragment f = getSupportFragmentManager().findFragmentByTag("search_criteria");
if (f != null)
{
ft.remove(f);
}
if (container == null)
{
searchCriteriaFragment.setCancelable(true);
searchCriteriaFragment.setHasOptionsMenu(false);
searchCriteriaFragment.show(getSupportFragmentManager(), "search_criteria");
}
else
{
ft.remove(searchCriteriaFragment);
ft.add(R.id.search_criteria_container, searchCriteriaFragment, "search_criteria");
ft.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == R.id.menu_item_search)
{
searchCriteriaFragment.show(getSupportFragmentManager(), "search_criteria");
}
return super.onOptionsItemSelected(item);
}
}
Specifically I was unable to get anything working unless I kept a static copy of the SearchCriteriaFragment and reused it whenever onCreate was called in the Activity. This seems very wrong to me.
SearchResultsFragment.java:
package org.nsdev.experiments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SearchResultsFragment extends android.support.v4.app.Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.results, container);
}
}
SearchCriteriaFragment.java:
package org.nsdev.experiments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SearchCriteriaFragment extends android.support.v4.app.DialogFragment
{
private static final String TAG = "SearchCriteriaFragment";
View v;
static SearchCriteriaFragment newInstance()
{
Log.e(TAG, "newInstance");
SearchCriteriaFragment d = new SearchCriteriaFragment();
return d;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (v == null)
{
v = inflater.inflate(R.layout.criteria, container, false);
}
else
{
if (v.getParent() instanceof ViewGroup)
{
Log.e(TAG, "Removing from viewgroup");
((ViewGroup)v.getParent()).removeAllViews();
}
}
return v;
}
}
You can see, here, that I had to work around a problem with the view being reused. There was an error stating that the view already had a parent and would need to be removed from it before it could be added to another parent. Again, this seems like I must be doing it the wrong way.
res/layout/main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="#+id/search_results"
android:name="org.nsdev.experiments.SearchResultsFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
res/layout-land/main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="#+id/search_criteria_container"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<fragment
android:id="#+id/search_results"
android:layout_toRightOf="#+id/search_criteria_container"
android:name="org.nsdev.experiments.SearchResultsFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
You can see from these two layouts, what I am trying to do. In the normal orientation, the FrameLayout doesn't exist, so we can detect this and show the DialogFragment instead. Otherwise, we can embed the DialogFragment into the FrameLayout.
The final two layouts I've just put placeholders in for the results and criteria layouts:
res/layout/criteria.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="#300F">
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="21dp"
android:paddingRight="30dp"
android:text="Test Criteria" />
</RelativeLayout>
res/layout/results.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="#f00">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:text="Results"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
I thought I had figured it out until I started rotating the device and checking the checkbox on an ICS device. Notice that I've set the color to be semi-transparent for the criteria.xml RelativeLayout background. What I noticed was that in landscape orientation, the embedded view was actually keeping old versions of the view around, and these would be overlaid with newer copies of the view each time I switched to portrait and back again. That's one of the reasons I tried to keep only one copy of the view returned in from the onCreateView of the SeachCriteriaFragment. This does not fix this problem.
I can only come to one conclusion: I must be doing this wrong. I suspect that the Fragments framework was never designed to do this kind of fragment reuse. How can I get a nice rotation working where in Portrait I show the DialogFragment as a dialog, and in Landscape it is embedded? Can I get the framework to do something like this more automatically?
I tried setting searchCriteriaFragment.setRetainInstance(true) and all hell broke loose, so I deleted that line immediately.
Thanks for any help getting me on the right track here.
I would say this.
On the phone make the SearchFormFragment an Activity and give it the theme Dialog.
Then the SearchResultsFragment is also a separate Activity on it's own.
The SearchForm xml would look like:
<LinearLayout >
<fragment class="com.your.package.ui.fragment.SearchFormFragment" />
</LinearLayout>
To get the Dialog theme:
<manifest . . . >
<application . . . >
<activity
android:name=".ui.phone.SearchFormFragmentActivity"
android:theme="#android:style/Theme.Dialog" . . . >
<activity
android:name=".ui.phone.SearchResultsFragmentActivity" . . . >
This makes orientation change simple using onSaveInstanceState and onRestoreInstanceState and the activity lifecycle.
Then on the tablet you have another activity with your two fragments in.
<activity
android:name=".ui.tablet.SearchFragmentActivity" . . . >
SearchFragmentActivity.xml:
<LinearLayout >
<fragment class="com.your.pacakage.ui.fragment.SearchFormFragment"/>
<fragment class="com.your.package.ui.fragment.SearchResultsFragment" />
</LinearLayout>
Simplified.
Related
I want to call a new activity when a list item is clicked from the drawer. I searched over the internet and what I got was to call the fragment of that activity. So, I wanted to know how to make a fragment of an activity.
P.S.- Sorry, if this question is silly. I'm still a noob.
A Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. Here the full explanation from android official developer guide.
Also on android developer guide you can find the code to properly create and use a fragment.
Create a fragment class:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class ExampleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_view, container, false);
}
}
Then you have to add the fragment to the activity layout:
<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.ExampleFragment"
android:id="#+id/example_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
Finally you can add the layout to your activity:
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.item_from_exampleLayout);
}
}
I took those examples from the android developer guide that i put above.
Anyway if i have understood your question this code should work:
list.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
Intent intent = new Intent(ThisClass.this, ClassToCall.class);
startActivity(intent);
}
});
This will start a new activity when a list item is clicked using an intent, but it doesn't need fragments.
i have problems to use a fragment in a fragment. The first fragment is a tab view an in one tab i want to have a multi-pane Layout like this:
The error is:
android.view.InflateException: Binary XML file line #8: Error
inflating class fragment
The tab fragment (SettingsFragmentBox):
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SettingsFragmentBox extends Fragment implements SettingsFragmentBoxList.OnItemSelectedListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_settings_box, container, false);
return rootView;
}
public void onBoxSelect(int id) {
SettingsFragmentBoxDetail fragment = (SettingsFragmentBoxDetail) getFragmentManager().findFragmentById(R.id.box_detail);
if (fragment != null && fragment.isInLayout()) {
fragment.setText(id);
} else {
Intent intent = new Intent(getActivity(),SettingsActivityBoxDetail.class);
intent.putExtra(SettingsActivityBoxDetail.EXTRA_ID, id);
startActivity(intent);
}
}
}
The xml (fragment_settings_box.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:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/box_list"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
class="de.resper.e2cast.SettingsFragmentBoxList"
tools:layout="#layout/fragment_settings_box_list">
</fragment>
<fragment
android:id="#+id/box_detail"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
class="de.resper.e2cast.SettingsFragmentBoxDetail"
tools:layout="#layout/fragment_settings_box_detail">
</fragment>
</LinearLayout>
Usually this is done using fragments in ACTIVITIES, not in other fragments. Are you sure you really want fragments in other fragments ?
The picture you are referring to is by the way showing this scenario (ACTIVITIES contain fragment A or B).
You should read http://developer.android.com/training/multiscreen/screensizes.html to handle different screensizes. There is an example with a layout containt two fragments in it. Also learn how to adapt to it by reading this http://developer.android.com/training/multiscreen/adaptui.html
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 relatively new to Android programming and really need assistance with this problem I am trying to solve. I have an application that revolves around three base activities. In the one activity - the largest by far - I have ten buttons in the UI that implement 16 different fragments (each with their own UIs) in a logical (i.e. step-by-step) fashion depending on what the user wants to accomplish.
So, for each of these 16 different fragments I need to activate and deactivate (enable and disable) various buttons in the UI depending on what the user is allowed to do when a specific fragment is active (i.e. at the front of the view stack or in view or visible to the user). In actual fact, I need to change (i.e. set) the states (i.e. enabled state) of all 10 buttons everytime a new fragment is loaded into the fragment placeholder/container to give the user a clear idea of where they are in this logical process of steps.
Please note: all 10 buttons are visible (i.e. should be visible) at all times (always) and must only be enabled or disabled depending on the fragment that is currently loaded or currently in view (i.e. displayed/visible to the user). OK, so let's look at some code...
Here is the Activity "DmpAct.java" (complete code to date) that I was referring to above...
package com.carzy.carzyapp;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
public class DmpAct extends Activity implements OnClickListener {
Fragment fragment;
Fragment newFragment;
FragmentManager fragMan;
Button birtListBtn, evenListBtn, appoListBtn, todoListBtn, specListBtn, dmpExitBtn;
#SuppressLint({ "NewApi", "CommitTransaction" })
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Hide the Title Bar of the Application --> Must come before setting the Layout...
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Hide the Status Bar of Android OS --> Can also be done later...
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Now you can draw the second Layout --> HomeScreen of the Application...
setContentView(R.layout.dmp_act);
// Instantiate the FragmentManager and FragmentTranstion...
FragmentManager fragMan = getFragmentManager();
FragmentTransaction fragTrans = fragMan.beginTransaction();
// Now you need to define or set the initial/start fragment to be loaded when the view is laid out...
DMPWelcFrag startFragment = new DMPWelcFrag();
fragTrans.add(R.id.dmpFragContainer, startFragment);
fragTrans.commit();
// Instantiate (or get references to) all buttons laid out in this Activity
Button birtListBtn = (Button) findViewById(R.id.dmp_bir_btn);
birtListBtn.setOnClickListener(this);
Button evenListBtn = (Button) findViewById(R.id.dmp_eve_btn);
evenListBtn.setOnClickListener(this);
Button appoListBtn = (Button) findViewById(R.id.dmp_app_btn);
appoListBtn.setOnClickListener(this);
Button todoListBtn = (Button) findViewById(R.id.dmp_tod_btn);
todoListBtn.setOnClickListener(this);
Button specListBtn = (Button) findViewById(R.id.dmp_spe_btn);
specListBtn.setOnClickListener(this);
Button dmpExitBtn = (Button) findViewById(R.id.dmp_exi_btn);
dmpExitBtn.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.dmp, menu);
return true;
}
#SuppressLint("NewApi")
#Override
public void onClick(View v) {
// Fragment newFragment;
// Set the DMP Fragment state here and pass it on to the FragmentTransaction module that follows..
if (v.getId() == R.id.dmp_bir_btn) {
newFragment = new BirtListFrag();
}
else if (v.getId() == R.id.dmp_eve_btn) {
newFragment = new EvenListFrag();
}
else if (v.getId() == R.id.dmp_app_btn) {
newFragment = new AppoListFrag();
}
else if (v.getId() == R.id.dmp_tod_btn) {
newFragment = new TodoListFrag();
}
else if (v.getId() == R.id.dmp_spe_btn) {
newFragment = new SpecListFrag();
}
else {
newFragment = new DMPWelcFrag();
}
if (v.getId() == R.id.dmp_exi_btn) {
Intent go2Main = new Intent(DmpAct.this, MainAct.class);
startActivity(go2Main);
}
else;
FragmentTransaction transact = getFragmentManager().beginTransaction();
transact.replace(R.id.dmpFragContainer, newFragment, "activeFrag");
transact.addToBackStack("activeFrag");
primeRelativeBtns();
transact.commit();
};
#SuppressLint("NewApi")
public void primeRelativeBtns() {
if (newFragment.equals("dmpBirtListFragTag")) {
birtListBtn.setEnabled(false);
evenListBtn.setEnabled(true);
appoListBtn.setEnabled(true);
todoListBtn.setEnabled(true);
specListBtn.setEnabled(true);
}
else if (newFragment.getTag() == "dmpEvenListFragTag") {
birtListBtn.setEnabled(true);
evenListBtn.setEnabled(false);
appoListBtn.setEnabled(true);
todoListBtn.setEnabled(true);
specListBtn.setEnabled(true);
} else;
}
}
Please note...at the time of submitting this question I had only completed 6 of the 10 buttons used by this activity (as is obvious in the code above)...
Anyway...on we go...
Here is the UI that is implemented for this activity by the "dmp_act.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:orientation="horizontal"
android:baselineAligned="false"
tools:context=".DmpAct">
<LinearLayout
android:id="#+id/leftButtonColumn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2705"
android:gravity="center"
android:paddingTop="5pt"
android:paddingBottom="10pt"
android:paddingLeft="8pt"
android:paddingRight="8pt"
android:orientation="vertical">
<ImageView
android:id="#+id/dmp_cat_sign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.0180"
android:contentDescription="#string/dmp_cat_sign"/>
<Button
android:id="#+id/dmp_bir_btn"
android:layout_width="wrap_content"
android:layout_height="23pt"
android:layout_weight="0.0164"
android:layout_marginBottom="13pt"/>
<Button
android:id="#+id/dmp_eve_btn"
android:layout_width="wrap_content"
android:layout_height="23pt"
android:layout_weight="0.0164"
android:layout_marginBottom="13pt"/>
<Button
android:id="#+id/dmp_app_btn"
android:layout_width="wrap_content"
android:layout_height="23pt"
android:layout_weight="0.0164"
android:layout_marginBottom="13pt"/>
<Button
android:id="#+id/dmp_tod_btn"
android:layout_width="wrap_content"
android:layout_height="23pt"
android:layout_weight="0.0164"
android:layout_marginBottom="13pt"/>
<Button
android:id="#+id/dmp_spe_btn"
android:layout_width="wrap_content"
android:layout_height="23pt"
android:layout_weight="0.0164"/>
</LinearLayout>
<LinearLayout
android:id="#+id/dmpFragContainer"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5350"
android:gravity="center"
android:orientation="vertical"
android:paddingTop="8pt"
android:paddingBottom="8pt">
<!-- <ImageView
android:id="#+id/dmp_wel_sta_wal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:alpha="1"
android:contentDescription="#string/dmp_welc_wall"/> -->
</LinearLayout>
<LinearLayout
android:id="#+id/rightButtonColumn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.1795"
android:gravity="center"
android:paddingTop="20pt"
android:paddingBottom="20pt"
android:paddingLeft="8pt"
android:paddingRight="8pt"
android:orientation="vertical">
<Button
android:id="#+id/dmp_edi_btn"
android:layout_width="wrap_content"
android:layout_height="0pt"
android:layout_weight="1"
android:layout_marginBottom="15pt"/>
<Button
android:id="#+id/dmp_sav_btn"
android:layout_width="wrap_content"
android:layout_height="0pt"
android:layout_weight="1"
android:layout_marginBottom="15pt"/>
<Button
android:id="#+id/dmp_add_btn"
android:layout_width="wrap_content"
android:layout_height="0pt"
android:layout_weight="1"
android:layout_marginBottom="15pt"/>
<Button
android:id="#+id/dmp_del_btn"
android:layout_width="wrap_content"
android:layout_height="0pt"
android:layout_weight="1"
android:layout_marginBottom="15pt"/>
<Button
android:id="#+id/dmp_exi_btn"
android:layout_width="wrap_content"
android:layout_height="0pt"
android:layout_weight="1"/>
</LinearLayout>
Before posting here I tried all the available solution already discussed here in SO...but to no avail. So to summarize the problem...I basically need a really good way (best-practise) of setting or changing all the buttons' enabled states everytime a new fragment is loaded (and displayed) to the user in the "dmpFragContainer".
I want to apologize beforehand if it seems like I am talking down to anyone, but I want to make sure everyone that reads this post will clearly understand the problem at hand. Please feel free to shred my code if you think I can implement better "best-practise" code structure - as I said before...I am new to Android coding and need all the help I can get.
Appreciate the help...
Cheers,
SilSur.
Thweeet! I solved the problem. Hello all... I managed to solve this problem I had with enabling or disabling all ten buttons just the way I want them to be disabled everytime a new fragment is loaded and visible to the user. The solution is that you have to implement this "enable/disable" code in the class files for each of the fragments. Pretty straightforward actually... So without further ado here is the solution in a more understandable fashion [code]...
This is the code from only one "BirtListFrag.java" of the 16 fragments I have running through my application...
package com.carzy.carzyapp;
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
#SuppressLint("NewApi")
public class BirtListFrag extends Fragment {
public static Button BirCatBtn;
public static Button EveCatBtn;
public static Button AppCatBtn;
public static Button TodCatBtn;
public static Button SpeCatBtn;
public static Button EdiFunBtn;
public static Button SavFunBtn;
public static Button AddFunBtn;
public static Button DelFunBtn;
public static Button ExiFunBtn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.dmp_birt_list_frag, container, false);
}
#Override
public void onActivityCreated (Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
/*** Get references to all the buttons you want to manipulate everytime this Fragment is loaded & visible in the viewport ***/
BirCatBtn = (Button) getActivity().findViewById(R.id.dmp_bir_btn);
EveCatBtn = (Button) getActivity().findViewById(R.id.dmp_eve_btn);
AppCatBtn = (Button) getActivity().findViewById(R.id.dmp_app_btn);
TodCatBtn = (Button) getActivity().findViewById(R.id.dmp_tod_btn);
SpeCatBtn = (Button) getActivity().findViewById(R.id.dmp_spe_btn);
EdiFunBtn = (Button) getActivity().findViewById(R.id.dmp_edi_btn);
SavFunBtn = (Button) getActivity().findViewById(R.id.dmp_sav_btn);
AddFunBtn = (Button) getActivity().findViewById(R.id.dmp_add_btn);
DelFunBtn = (Button) getActivity().findViewById(R.id.dmp_del_btn);
ExiFunBtn = (Button) getActivity().findViewById(R.id.dmp_exi_btn);
/*** Now you can manipulate whatever attributes (***See Below***) of the buttons u created references to ABOVE ***/
BirCatBtn.setEnabled(false);
EveCatBtn.setEnabled(true);
AppCatBtn.setEnabled(true);
TodCatBtn.setEnabled(true);
SpeCatBtn.setEnabled(true);
EdiFunBtn.setEnabled(false);
SavFunBtn.setEnabled(false);
AddFunBtn.setEnabled(true);
DelFunBtn.setEnabled(false);
ExiFunBtn.setEnabled(true);
}
}
As you can see...it is pretty logical. Anyway. I owe this breakthrough to "Greensy" who answered a question posted by "ColorFrog" on a similar problem that I had ==> here is the jump if you want to check out what I am talking about..."Disabling buttons in a Fragment".
Anywho...at the time of posting this reply I had been a member of S.O. for only 5 days and thus I couldn't "upvote" Greensy's answer as I didn't have that privilege at the time. So, since his answer really helped me solve my problem, I decided the least I could do was post this reply and thank him/her upfront. So thanks mate...I definitely owe u something (hmm...a beer maybe?!). Who knows. Anyway, I hope a will get to return the favor one day.
Cheers,
Shore-T.
package com.iperetz1.android.testbutton1;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class TestButton extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button test2 = (Button)findViewById(R.id.test2);
test2.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
setContentView(R.layout.test2);;
}
});
Button other = (Button)findViewById(R.id.backmain);
other.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
setContentView(R.layout.main);;
}
});
}
}
main.xls
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="#+id/widget0"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<Button
android:id="#+id/test2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test2"
android:layout_x="24px"
android:layout_y="165px"
>
</Button>
</AbsoluteLayout>
test2.xml
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="#+id/widget0"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<Button
android:id="#+id/backmain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="backmain"
android:layout_x="24px"
android:layout_y="165px"
>
</Button>
</AbsoluteLayout>
findViewById is a lot simpler than people tend to think it is. It traverses the view hierarchy looking for a view with the given ID. If it's not found, findViewById returns null.
You started by setting the content view to your main layout but later on you tried to findViewById(R.id.backmain). Since there is no view with that ID in your main layout, it returns null. At that point attempting other.setOnClickListener will fail. You will only be able to do this when your button actually exists in the view hierarchy.
There's nothing inherently wrong with dynamically changing your view hierarchy, but you'll have to handle some things differently if you go that route. (Such as when you wire up events to views that don't exist during onCreate like you're trying to do above.)
As #Cristian Castiblanco said, changing the view dynamically is causing the problem, for these kind of scenarios, you have to create separate activities and invoke them using intents and pass data between them using bundles.