I am using PreferenceFragment to get preferences from user. I have designed a simple preference file having only one EditPreference. I have created the following preferencefragement file
public class fragact extends PreferenceFragment
{
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.fragpref);
}
}
In my main activity i am trying to show the fragment at the click of a button.However the fragment comes transparent and is not very visible and the underlying screen is seen through it.
why the fragment does not come proper. i created another activity and used it to show the fragment.it worked properly .but why can we show the fragment directly rather than showing through another activity in its oncreate and calling it through startActivity in class fragprefmain.
public class fragprefmain extends Activity
{
EditText et;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.fragpref);
et=(EditText)findViewById(R.id.editText1);
}
public void showp(View v)
{
FragmentManager fm=getFragmentManager();
FragmentTransaction ft=fm.beginTransaction();
ft.replace(android.R.id.content, new fragact());
ft.commit();
}
public void showval(View v)
{
SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(this);
et.setText(sp.getString("ekey", "no valued given"));
}
maybe try to replace the opaque id
android.R.id.content
with your own layout id that you define in your activity xml file
it can be an empty layout but you must give the layout an id, say:
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/my_layout_id">
so now you get:
.replace/add(R.id.my_layout_id, new fragact());
You might as well create a preferenceActivity as given by WannaGetHigh in How do you create Preference Activity and Preference Fragment on Android?
Related
Basically I've got an ActionBarActivity that loads activity_main.xml which contains my ListFragment
My ActionBar has an Add button on it, to add items to the list.
Problem I've run into now, is how do I handle the Add and pass the information to the ListFragment to populate the ListView?
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//activity_main only contains <fragment ... /> to add my ListFragment
}
....
// This is called from onOptionsItemSelected
private void showAddDialog() {
FragmentManager fm = getSupportFragmentManager();
InputDialog inputDialog = new AddInputDialog();
inputDialog.setOnUpdateListener(new InputDialog.onUpdateListener(){
#Override
public void onUpdate(Item item){
//I'm lost at what to do here...
}
});
inputDialog.show(fm, "fragment_dialog_input");
}
EDIT
Got it working using findFragmentById(), and posted answer below.
I kept trying to get it to work using findFragmentByTag() and even though I had a TAG set in my fragment, and when debugging it(the TAG) showed correctly, for some reason would always return null.
Since the fragment is defined in activity_main.xml use findFragmentById using the specified android:id then you can call your public function within the ListFragment to update the list and notify adapter.
private void showAddDialog() {
final FragmentManager fm = getSupportFragmentManager();
InputDialog inputDialog = new AddInputDialog();
inputDialog.setOnUpdateListener(new InputDialog.onUpdateListener(){
#Override
public void onUpdate(Item item){
ListFragment lf = (ListFragment)fm.findFragmentById(R.id.listFragment);
lf.addItem(item);
}
});
inputDialog.show(fm, "fragment_dialog_input");
}
I've recently tried to use an interface for fragment-activity communication. The idea is that when a button is pressed in a fragment, it retrieves data from an EditText in the same fragment, it then sends the string to the MainActivty - this controls all my fragments - which then starts another fragment and delivers the string to this fragment for use later, however, I'm having trouble initially setting up the first interface which sends the data. Unfortunately nothing happens, and I cannot therefore get to the next fragment which should be displayed. Additionally I have tried using getActivity() but it cannot find the associated method within the fragment, leading me to believe that the fragments somehow aren't directly connected to MainActivity (I've only just grasped basics of Java and a little of Android, just learning.)
I've listed the relevant information below, thanks for the assistance!
Fragment
public class CreateWorkoutFragment extends Fragment implements OnClickListener {
View rootViewCreateWorkoutFragment;
EditText editTextWorkoutName;
// Using an ImageView for custom button
ImageView buttonNext;
String valueCreateWorkoutEditText;
OnDataPass dataPasser;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootViewCreateWorkoutFragment = inflater.inflate(R.layout.fragment_create_workout, container, false);
buttonNext = (ImageView) rootViewCreateWorkoutFragment.findViewById(R.id.button_workout_name_next);
editTextWorkoutName = (EditText) rootViewCreateWorkoutFragment.findViewById(R.id.edit_text_workout_name);
buttonNext.setOnClickListener(this);
return rootViewCreateWorkoutFragment;
}
public interface OnDataPass {
public void onDataPass(String data);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
dataPasser = (OnDataPass) activity;
}
public void passData(String data) {
dataPasser.onDataPass(data);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_workout_name_next:
valueCreateWorkoutEditText = editTextWorkoutName.getText().toString();
passData(valueCreateWorkoutEditText);
break;
}
}
}
Main Activity
public class MainActivity extends FragmentActivity implements OnClickListener, CreateWorkoutFragment.OnDataPass {
ImageView buttonCreate;
Fragment newFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.AppThemeBlue);
setContentView(R.layout.activity_main);
buttonCreate = (ImageView) findViewById(R.id.create_foreground);
buttonCreate.setOnClickListener(this);
FragmentManager fragManager = getSupportFragmentManager();
FragmentTransaction tranManager = fragManager.beginTransaction();
CreateWorkoutFragment createWorkoutFrag = new CreateWorkoutFragment();
// fragment_change is just the area in XML where fragments switch
tranManager.add(R.id.fragment_change, createWorkoutFrag);
tranManager.commit();
newFragment = null;
}
#Override
public void onDataPass(String data) {
// CreateFragment is not to be confused with CreateWorkoutFragment
// CreateFragment is the fragment I'm trying to start when any strings
// are obtained from CreateWorkoutFragment
newFragment = new CreateFragment();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
// create_foreground is just an ImageView used as a button
// Additionaly, other buttons are used to create other fragments,
// I've cut them out currently as they are not nessesary which is
// why CreateWorkoutFragment is only button and default currently
case R.id.create_foreground:
newFragment = new CreateWorkoutFragment();
break;
default:
newFragment = new CreateWorkoutFragment();
}
FragmentTransaction tranManager = getSupportFragmentManager().beginTransaction();
tranManager.replace(R.id.fragment_change, newFragment);
tranManager.addToBackStack(null);
tranManager.commit();
}
}
Sorry the code isn't exactly tidy, however, it was the most relevant code cut out from a large class. As I said, I have tried other methods yet cannot get any response from MainActivity either way. Thanks in advance!
Just before I posted: Got the app to write logcat messages to me, it manages to pass the data when the button is clicked - at least I think, and is something to do with the fragment not starting! At MainActivity>onDataPass()>new Fragment = new CreateFragment() Any ideas? As mentioned before, other buttons do exist and manage to change the fragment. However, were cutout to reduce amount of code posted.
getActivity() but it cannot find the associated method within the fragment
This is because getActivity() returns an Activity, not a MainActivity which is your custom subclass. You can easily fix this with a cast. For example, in your fragment, you can do this:
OnDataPass main = (OnDataPass) getActivity();
main.onDataPass(message);
Since such a cast is required, the interface seems to get in the way in my opinion. You can just as easily cast directly to MainActivity:
MainActivity main = (MainActivity) getActivity();
main.onDataPass(message);
I have two fragments in a activity .one has edit field and second has textview .both are visible at time. I have to enter text into edit field and that text should be displayed on the second fragment which a textview. I have one solution , i can make static textview in secodn fragment but i think it is not best way to do that.Kindly guide me.
From the Fragment documentation:
Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
So i would suggest something like this:
You have two fragments and one associated activity
Code for Activity
public class MainActivity extends FragmentActivity{
//On create stuff .....
#Override
public void onButtonPressed(String msg) {
// TODO Auto-generated method stub
LayOutTwo Obj=(LayOutTwo) getSupportFragmentManager().findFragmentById(R.id.frag_2);
Obj.setMessage(msg);
}
}
Code For Layout 1:
Button but=(Button)root.findViewById(R.id.button1);
but.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
buttonListener.onButtonPressed("Message From First Fragment");
}
});
Code For Layout 2:
void setMessage(String msg){
TextView txt=(TextView)root.findViewById(R.id.textView1);
txt.setText(msg);
}
This how you can easily pass data between fragments using its associated activity.
Hope this helps
I'm trying to add a PreferenceFragmentin my application. The problem is, it's auto placed on top of my NavigationDrawer.
public class SetPreferenceActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
navigationDrawer(); // Loads the NavigationDrawer
getFragmentManager().beginTransaction().replace(android.R.id.content,
new Settings()).commit();
}
As you can see I load the "SettingsFragment" and replace the content with it? (I'm unsure) but it places it on top of everything else.. Here's my Settings fragment.
public class Settings extends PreferenceFragment {
static final String TAG = "MAIN";
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
Everything work as expected, BUT the PreferenceFragment are loaded in front, covering up the NavigationDrawer slideout, I tried calling bringToFront(); on the listview, with no luck.
A picture for reference :
Is it possible to tell the fragment to load behind the listview? I also tought about loading the fragment in a ViewPager, but I get an error that the Pager Adapter wont accept fragments of type PreferenceFragment.
Don't replace android.R.id.content, use the the id of the FrameLayout you have in the layout that contains your DrawerLayout.
In addition to what adneal said (in case others have the same problem):
The Activity which calls the PreferenceFragment needs to have the setContentView() method if you extend the Activity with your NavigationDrawer:
public class SetPreferenceActivity extends MyNavigationDrawer {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
getFragmentManager().beginTransaction().replace(R.id.drawer_frame_layout,
new Settings()).commit();
}
And the settings.xml should only contain a FrameLayout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
I had same issue and i resolved it by replacing android.R.id.content to R.id.container.
I am using two fragments in my activity.Initially I will add one fragment to the activity.Then using listener in first fragment I want replace it with second fragment. I tried as per my understanding ,but it is not replacing. It is showing both fragments overlapped.
Here is my code:
// MainActivity
public class MainActivity extends Activity {
Fragment Fragment_one;
Button one;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//one=(Button) findViewById(R.id.button1);
//one.setOnClickListener(new View.OnClickListener() {
//#Override
//public void onClick(View arg0) {
// TODO Auto-generated method stub
FragmentManager man=getFragmentManager();
FragmentTransaction tran=man.beginTransaction();
Fragment_one=new Fragment1();
tran.add(R.id.fragment_container, Fragment_one);//tran.
tran.addToBackStack(null);
tran.commit();
//}
//});
}
}
//fragment code
public class Fragment1 extends Fragment{
Button add;
Fragment2 fragment_two;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
//return super.onCreateView(inflater, container, savedInstanceState);
View view=inflater.inflate(R.layout.fragment_1, container,false);
add=(Button) view.findViewById(R.id.button1);
fragment_two =new Fragment2();
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentTransaction t=getActivity().getFragmentManager().beginTransaction();
t.remove( new Fragment1());
t.replace(R.id.fragment1, fragment_two);t.addToBackStack(null);
t.commit();
//t.addToBackStack(null);
}
});
return view;
}
}
Couple of things I see in your code.
t.remove(new Fragment1());
This line of code won't do anything because you're trying to remove a new instance of Fragment1, not the instance you originally added.
t.replace(R.id.fragment1, fragment_two)
This the first parameter should be the id of the container "R.id.fragment_container" not R.id.fragment1.
t.addToBackStack(null);
This code may or may not be needed based on whether you want to allow the user to press the 'back' button to go back to fragment_one after they've arrived at fragment2.
Use this line of code in your fragmented xml files and save your day.
Remember please to Add this line into parents and all layout fragment xml files.
android:background="?android:windowBackground"
Why not inflate both fragments and use your listener to toggle their visibility? – brbaker
Can you help me how to toggle ?#brbaker – Riding Cave
add interface and implement in activity and override method. Then add onClickListener and set to trigger method in interface. Then use fragment manager to do show() and hide() transactions on fragments as needed.
http://developer.android.com/reference/android/app/FragmentTransaction.html
show(Fragment fragment)-Shows a previously hidden fragment.
hide(Fragment fragment)-Hides an existing fragment.