This question already has answers here:
NullPointerException accessing views in onCreate()
(13 answers)
Closed 8 years ago.
I've been looking at many examples of getting the pointers to the displays in the onCreate function but every time I do this I get null returns from my findViewById functions but if I do it elsewhere it works just fine. What am I missing to get this to work right?
Thanks for any help I must be missing something
EditText messageField;
AutoCompleteTextView numberField;
EditText countField;
TextView messageDisplay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
sms = SmsManager.getDefault();
preferences = PreferenceManager.getDefaultSharedPreferences(this);
messageField = (EditText) findViewById(R.id.message);
numberField = (AutoCompleteTextView) findViewById(R.id.number);
countField = (EditText) findViewById(R.id.count);
messageDisplay = (TextView) findViewById(R.id.display_message);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
fragment_main.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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:background="#000000"
tools:context="com.example.last.MainActivity$PlaceholderFragment" >
<AutoCompleteTextView
android:id="#+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/send"
android:layout_marginTop="49dp"
android:textColor="#android:color/white"
android:inputType="numberSigned"
android:selectAllOnFocus="true"
android:ems="10"
android:text="#string/phone_number" >
<requestFocus />
</AutoCompleteTextView>
<Button
android:id="#+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/message"
android:layout_marginRight="25dp"
android:layout_marginTop="70dp"
android:onClick="sendMessage"
android:textColor="#android:color/white"
android:text="#string/send_button" />
<EditText
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/send"
android:layout_below="#+id/number"
android:layout_marginTop="61dp"
android:ems="10"
android:inputType="textMultiLine"
android:textColor="#android:color/white"
android:selectAllOnFocus="true"
android:text="#string/default_message" />
<EditText
android:id="#+id/count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/message"
android:layout_marginTop="32dp"
android:ems="4"
android:maxEms="4"
android:inputType="numberSigned"
android:textColor="#android:color/white"
android:text="#string/default_count" />
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/message"
android:layout_below="#+id/send" />
<TextView
android:id="#+id/display_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/progressBar1"
android:layout_below="#+id/progressBar1"
android:layout_marginTop="45dp"
android:layout_toLeftOf="#+id/send"
android:textColor="#android:color/white"
android:text="#string/default_display_message" />
<TextView
android:id="#+id/char_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/message"
android:layout_alignBottom="#+id/message"
android:layout_alignParentRight="true"
android:text="18/160" />
<android.gesture.GestureOverlayView
android:id="#+id/easter_egg_gesture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/display_message" >
</android.gesture.GestureOverlayView>
<Button
android:id="#+id/eeb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/easter_egg_gesture"
android:layout_alignParentLeft="true"
android:background="#000000"
android:onClick="easterEgg" />
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.app.joebot.MainActivity"
tools:ignore="MergeRootFrame" />
From your code, looks like your components like EdiText and TextView are residing in Fragment_main.xml but you are referencing them in Activity_main.xml.
Change your initialization of components to correct layout.
You are trying to reference Views in your Fragment's layout from your Activity. This is not possible as the Views reside in the Fragment's layout and not the Activity's one which is where it tries to look. You should define these Views in the Fragment that they are in and then expose them through methods if you desire access from your Activity.
You should however not make that decision lightly as it is recommended to keep Fragment details in your Fragments and only expose what you need to outside of that. Such as results or values instead of whole Views.
public MyFragment extends Fragment implements View.OnClickListener
{
private Button myButton;
private EditText myEditText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_input_submit, container, false);
myButton = (Button) view.findViewById(R.id.myButton);
myEditText = (EditText) view.findViewById(R.id.myEditText);
myButton.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v)
{
// keep the Fragment interaction in the Fragment
switch (v.getId())
{
case R.id.myButton:
Log.v("example fragment", "myButton was pressed");
break;
default:
break;
}
}
public EditText getMyEditText()
{
// you could get the EditText to use in your Activity
return this.myEditText;
}
public String getEditTextContents()
{
// or you could just allow access the data
return this.myEditText.getText().toString();
}
}
To make use of this you will need to keep a reference to your Fragment in your Activity:
public MyActivity extends FragmentActivity
{
private MyFragment myFragment;
#Override
public void onCreate(Bundle bundle)
{
super.onCreate(bundle);
setContentView(R.layout.activity_main);
myFragment = new MyFragment();
getFragmentManager().beginTransaction()
.add(R.id.container, myFragment).commit();
}
...
}
Then to get access to the Fragment's information you would call either:
EditText myEditText = myFragment.getMyEditText();
or
String editTextContents = myFragment.getEditTextContents();
depending on your choice.
You can also communicate from the Fragment to the Activity using Interfaces. See this previous answer I made to a related question here for details on that and more examples of this.
The problem is, the following four lines of code:
messageField = (EditText) findViewById(R.id.message);
numberField = (AutoCompleteTextView) findViewById(R.id.number);
countField = (EditText) findViewById(R.id.count);
messageDisplay = (TextView) findViewById(R.id.display_message);
These lines should come AFTER your fragment transaction:
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
getFragmentManager().executePendingTransactions();
}
messageField = (EditText) findViewById(R.id.message);
numberField = (AutoCompleteTextView) findViewById(R.id.number);
countField = (EditText) findViewById(R.id.count);
messageDisplay = (TextView) findViewById(R.id.display_message);
This should work.
Note also that I've added the executePendingTransactions() method to your code (it is required in this case). However, I'd prefer to handle those Views in the Fragment (unless there's a good reason to use them in the Activity itself). Remove these lines from the onCreate() method of your Activity and add them to the onViewCreated() method of your PlaceholderFragment :
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
messageField = (EditText) view.findViewById(R.id.message);
numberField = (AutoCompleteTextView) view.findViewById(R.id.number);
countField = (EditText) view.findViewById(R.id.count);
messageDisplay = (TextView) view.findViewById(R.id.display_message);
}
Whatever you would like to do with those Views can be done in this method. Hope this helps ... :)
Related
In my Fragment, I have three controls: two ImageViews and a Button:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent"
android:id="#+id/rel_layout"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="#ffffffff"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:textStyle="bold"
android:visibility="visible"
android:textSize="25sp"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp" />
<ImageView
android:id="#+id/forward"
android:background="#drawable/chevronright"
android:layout_below="#+id/heading"
android:layout_alignParentEnd="true"
android:layout_width="50dp"
android:layout_height="50dp" />
<ImageView
android:id="#+id/back"
android:background="#drawable/chevronleft"
android:layout_below="#+id/heading"
android:visibility="invisible"
android:layout_alignParentStart="true"
android:layout_width="50dp"
android:layout_height="50dp" />
<Button
android:id="#+id/skip_button"
android:text="#string/skip_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_below="#+id/back"
android:layout_alignParentStart="true"
android:textStyle="bold"
android:layout_alignParentBottom="true"
android:gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/heading" >
<TextView
android:id="#+id/body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="normal"
android:visibility="visible"
android:textSize="20sp" />
</LinearLayout>
</RelativeLayout>
In the fragment, I define onClickListeners for all three controls:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
SharedPreferences sharedPref = getActivity().getSharedPreferences("WDWHIC settings", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("lastPage", INTRO);
editor.commit();
View view = inflater.inflate(R.layout.fragment_intro, container, false);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(R.string.intro_page_full);
RelativeLayout topLayout = getActivity().findViewById(R.id.topLayout);
topLayout.setVisibility(View.INVISIBLE);
final Animation in = new AlphaAnimation(0.0f, 1.0f);
in.setDuration(500);
RelativeLayout rel_layout = view.findViewById(R.id.rel_layout);
Resources res = getResources();
pages = res.getStringArray(R.array.pages_array);
heading = rel_layout.findViewById(R.id.heading);
heading.setText(pages[pageNum]);
forward = rel_layout.findViewById(R.id.forward);
forward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
back.setVisibility(View.VISIBLE);
pageNum += 2;
heading.setText(pages[pageNum]);
body.startAnimation(in);
body.setText(pages[pageNum + 1]);
body.scrollTo(0, 0);
if (pageNum == 2 * MAX_PAGES) forward.setVisibility(View.INVISIBLE);
}
});
back = rel_layout.findViewById(R.id.back);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
forward.setVisibility(View.VISIBLE);
pageNum -= 2;
heading.setText(pages[pageNum]);
body.startAnimation(in);
body.setText(pages[pageNum + 1]);
body.scrollTo(0, 0);
if (pageNum == 0) back.setVisibility(View.INVISIBLE);
}
});
skip = rel_layout.findViewById(R.id.skip_button);
skip.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditProfileFragment editProfileFragment = new EditProfileFragment();
FragmentManager manager = getActivity().getSupportFragmentManager();
manager.beginTransaction().replace(R.id.fragment_container, editProfileFragment, editProfileFragment.getTag()).commit();
getActivity().overridePendingTransition(R.anim.fadein, R.anim.fadeout);
}
});
body = rel_layout.findViewById(R.id.body);
body.startAnimation(in);
body.setText(pages[pageNum + 1]);
body.setMovementMethod(new ScrollingMovementMethod());
return view;
}
If I click on the 'skip' button while on the first page, its onClick() method gets called. But if I click on forward or back, it doesn't unless I return to the first page. What's up with this? Why should advancing pages make a difference?
Try adding android:clickable="true" to your image views.
In the documentation:
android:clickable Defines whether this view reacts to click events.
https://developer.android.com/reference/android/view/View#attr_android:clickable
Therefore, in theory, the View's onClickListener won't be fire if clickable is not set to true.
I would try setting the onClickListener functionality in the class that extends FragmentActivity.
In the class that implements your onCreateView method define a static handler and initialized it with the static handler that should be defined in the class that extends FragmentActivity.
from the class that implements onCreateView create an android message to send to the static handler of your class that extends FragmentActivity. In this message send an object which is your button that will implement the onClickListener. Note: Create and send this message from inside your onCreateView.
Once the message is received inside the class that extends FragmentActivity, send the
object that arrives in the message( which is a view that is actually your button) as a parameter to a private method that resides inside your class that extends FragmentActivity.
Inside this private method try to set the onClickListener functionality.
I don't know why this should work, but I moved the button above the heading, without changing anything else, and now onClick() gets called from every page.
<Button
android:id="#+id/skip_button"
android:text="#string/skip_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_alignParentEnd="true"
android:textStyle="bold"
android:layout_marginTop="10dp"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="#+id/skip_button"
android:textStyle="bold"
android:visibility="visible"
android:textSize="25sp"
android:layout_marginStart="10dp" />
I created an empty activity in my Android project, and added one TextView and one Button to it, like so:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_margin="10dp"
android:onClick="onClick"
tools:context="com.radical.pillbox.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/CloseActivityCross"
android:text="#string/cross"
android:textSize="50sp"
android:padding="10dp"
android:fontFamily="#font/montserrat_bold"
android:textColor="#color/pillbox_green_primary_dark" />
<TextView
android:id="#+id/IntroString"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/CloseActivityCross"
android:fontFamily="#font/montserrat_light"
android:padding="10dp"
android:text="Welcome to Pillbox."
android:textColor="#000000"
android:textSize="30sp"
android:gravity="left"
android:textAlignment="gravity"/>
<EditText
android:id="#+id/EmailEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/IntroString"
android:layout_marginLeft="10dp"
android:alpha="0.64"
android:fontFamily="#font/montserrat_light"
android:hint="email#example.com"
android:inputType="textEmailAddress"
android:textColor="#color/pillbox_background_dark"
android:textColorHint="#color/pillbox_accent_green" />
<EditText
android:id="#+id/PasswordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/EmailEditText"
android:layout_marginStart="10dp"
android:alpha="0.64"
android:fontFamily="#font/montserrat_light"
android:hint="password"
android:inputType="textPassword"
android:textColor="#color/pillbox_background_dark"
android:textColorHint="#color/pillbox_accent_green" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/FooterString"
android:textColor="#000000"
android:textSize="12sp"
android:text="2018."
android:layout_centerHorizontal="true"
android:textAlignment="center"
android:fontFamily="#font/montserrat_light"
android:layout_alignParentBottom="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:id="#+id/SignInButton"
android:background="#drawable/round_button"
android:text="Sign In"
android:textSize="15sp"
android:textColor="#color/pillbox_green_primary_dark"
android:layout_below="#id/PasswordEditText"/>
<Button
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:id="#+id/SignUpButton"
android:background="#drawable/round_button"
android:text="Sign Up"
android:textSize="15sp"
android:textColor="#color/pillbox_green_primary_dark"
android:layout_below="#id/PasswordEditText"
android:layout_toRightOf="#id/SignInButton"/>
</RelativeLayout>
My MainActivity.java file is:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText email = (EditText) findViewById(R.id.EmailEditText);
EditText password = (EditText) findViewById(R.id.PasswordEditText);
TextView close = (TextView) findViewById(R.id.CloseActivityCross);
Button sign_up = (Button) findViewById(R.id.SignUpButton);
Button sign_in = (Button) findViewById(R.id.SignInButton);
email.setOnClickListener(MainActivity.this);
password.setOnClickListener(MainActivity.this);
sign_in.setOnClickListener(MainActivity.this);
close.setOnClickListener(MainActivity.this);
}
#Override
public void onClick(View view) {
EditText email = (EditText) findViewById(R.id.EmailEditText);
EditText password = (EditText) findViewById(R.id.PasswordEditText);
TextView close = (TextView) findViewById(R.id.CloseActivityCross);
Button sign_up = (Button) findViewById(R.id.SignUpButton);
Button sign_in = (Button) findViewById(R.id.SignInButton);
switch (view.getId()) {
case (R.id.SignInButton):
Log.d("Event:", "Signed in with correct credentials.");
break;
case (R.id.CloseActivityCross):
Toast.makeText(MainActivity.this, "Closing.", Toast.LENGTH_SHORT).show();
MainActivity.this.finish();
Log.d("Cross:", "Activity closed");
break;
}
}
}
In my main activity, I created cases in a switch-statement to handle the OnClick Events, but only the first case defined works. The remaining cases never trigger for some reason or trigger after an extended delay. To diagnose where the problem occurs, I have:
1. Tried to change the order in which I add the listeners
2. Changed cases with the first being CloseActivityCross once and SignInButton the next. Each time, only the first case works properly. Why does this happen? I should mention that in one trial, things began working perfectly for a while, and now the same issue is cropping up.
Don't re-initialize your views in onClick method i.e., remove these lines from the OnClick method and it should be good.
EditText email = (EditText) findViewById(R.id.EmailEditText);
EditText password = (EditText) findViewById(R.id.PasswordEditText);
TextView close = (TextView) findViewById(CloseActivityCross);
Button sign_up = (Button) findViewById(R.id.SignUpButton);
Button sign_in = (Button) findViewById(R.id.SignInButton);
what's happening is, when you press any of these views, they lose their onClickListeners as you are initializing the above views again.
Edited as OP added additional code.
EDIT 2:
Remove OnClick for root element RelativeLayout
<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"
android:layout_margin="10dp"
tools:context="com.radical.pillbox.MainActivity">
Listeners are OK in java code . The problem is in xml . Your parent layout is RelativeLayout and you have use rule android:layout_below .
In some places you have used "#id instead of "#+id . So this will make overlap the views . Make it write as "#+id in all android:layout_below tags and remove android:onClick="onClick" from root layout . see if it works .
Suggestion :- If all of your widgets aligned vertically then Use LinearLayout with vertical orientation .
I've got an app based on Sliding Tabs layout. I want to call the addMedicine method in the PageFragment class from an XML layout with a Button. The issue is that i cannot assign the method to the Button onClick event.
Here's the PageFragment class:
public class PageFragment extends Fragment {
public static final String ARG_PAGE = "ARG_PAGE";
private int mPage;
// TEMP VARIABLES //
ListView ItemsLst;
String[] Items = {"Medicine 1", "Medicine 2", "Medicine 3"};
TextView output;
EditText nameFld;
EditText formatFld;
EditText amountFld;
EditText exp_dateFld;
EditText timeFld;
DBManager dbAdapt = new DBManager(getActivity());
public static PageFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
PageFragment fragment = new PageFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments().getInt(ARG_PAGE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = null;
switch(mPage)
{
case 1:
view = inflater.inflate(R.layout.layout_sqltest, container, false);
nameFld = (EditText) view.findViewById(R.id.nameFld);
formatFld = (EditText) view.findViewById(R.id.formatFld);
amountFld = (EditText) view.findViewById(R.id.amountFld);
exp_dateFld = (EditText) view.findViewById(R.id.exp_dateFld);
timeFld = (EditText) view.findViewById(R.id.timeFld);
return view;
case 2:
view = inflater.inflate(R.layout.layout_settings, container, false);
return view;
case 3:
view = inflater.inflate(R.layout.layout_info, container, false);
return view;
}
return view;
}
public void addMedicine() // The method i want to call
{
String name = nameFld.getText().toString();
String format = formatFld.getText().toString();
int amount = Integer.parseInt(amountFld.getText().toString());
String exp_date = exp_dateFld.getText().toString();
String time = timeFld.getText().toString();
long id = dbAdapt.addMedicine(name, format, amount, exp_date, time);
}
}
And here is the layout_sqltest XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Name"
android:id="#+id/nameLbl"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/nameFld"
android:layout_gravity="center_horizontal"
android:inputType="text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Format"
android:id="#+id/formatLbl"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/formatFld"
android:layout_gravity="center_horizontal"
android:inputType="text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Amount"
android:id="#+id/amountLbl"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/amountFld"
android:layout_gravity="center_horizontal"
android:inputType="text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Expiration Date"
android:id="#+id/exp_dateLbl"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/exp_dateFld"
android:layout_gravity="center_horizontal"
android:inputType="text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Time"
android:id="#+id/timeLbl"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/timeFld"
android:layout_gravity="center_horizontal"
android:inputType="text" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Medicine"
android:id="#+id/addMedicineBtn"
android:layout_gravity="center_horizontal" />
</LinearLayout>
The addMedicineBtn is the button i want to call the method with.
Someone can help me? I really need that!
Thank you in advance!
EDIT: I tried giving to addMedicine method the View param, but it still doesn't appear in the available methods for the addMedicineBtn in the onClick properties (I'm using Android Studio).
Try to use onClickListener
view.findViewById(R.id.addMedicineBtn).setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
addMedicine();
}
});
You must add tools:context="PageFragment" line to the container (LinearLayout) of PagerFragment's layout file (layout_sqltest). Then onClick() method will find methods in PagerFragment class.
I am making an activity which has a section for comments based on addresses inputed by the user.
The user will add a new comments section by pressing a button. This is a non fixed number of sections, so I have initially added this section as a fragment in the xml.
I have an onClick function that adds another fragment to the linearlayout.
My problem is that the new fragments always add to the top of the linearlayout , i.e. above the existing fragment/fragments (i.e. the new fragment will push all the other fragments down).
How can I add the new fragment so that it displays below the existing fragment?
Code in .java file:
public class SpecialReportAdden extends ActionBarActivity {
int numOfFragments;
LinearLayout addenHolder;
TextView report;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_special_report_adden);
numOfFragments=1;
Button addenSave = (Button)findViewById(R.id.btnAddendumSave);
Button addenAddComment = (Button)findViewById(R.id.btnAddendumAddComment);
addenHolder =(LinearLayout)findViewById(R.id.AddenLinLayHolder);
addenSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//this should save all comments including those added in dynamically produced fragments
//save database
Intent i = new Intent (SpecialReportAdden.this, MenuPage.class);
startActivity(i);
}
});
addenAddComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("number of Fragments at start of OnClick", Integer.toString(numOfFragments));
Fragment newAddenFrag = addNewfragment(numOfFragments);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.AddenLinLayInnerHolder, newAddenFrag);
ft.addToBackStack(null);
ft.commit();
numOfFragments++;
Log.i("number of Fragments updated", Integer.toString(numOfFragments));
}
});
}
public Fragment addNewfragment(int number) {
AddendumLinInputFragment adden = new AddendumLinInputFragment();
TextView tx = (TextView) findViewById(R.id.txtVAddendumFragReportNum);
tx.setText("Report "+number+" :");
tx.setTextColor(Color.BLACK);
TextView address = (TextView)findViewById(R.id.txtVAddendumFragAddress);
address.setText("A new address");
address.setTextColor(Color.BLUE);
return adden;
}
xml file for the .java activity
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.danielt.pestcontrol.SpecialReportAdden"
android:id="#+id/RellayAddenComments">
<TextView
android:id="#+id/txtVAddendumTitle" android:text="Service Report Addendum" android:textStyle="bold" android:layout_centerHorizontal="true" android:elegantTextHeight="true" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"/>
<TextView
android:id="#+id/txtVAddendumTechName"
android:layout_below="#+id/txtVAddendumTitle"
android:layout_marginTop="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Technician Name: "
android:textSize="18sp"
/>
<TextView
android:id="#+id/txtVAddendumDate"
android:layout_below="#+id/txtVAddendumTechName"
android:layout_marginTop="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Date: "
android:textSize="18sp"
/>
<ScrollView
android:id="#+id/scrlVAddendum"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/txtVAddendumDate">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/AddenLinLayHolder"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/AddenLinLayInnerHolder"
android:orientation="vertical">
<fragment
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:name="com.example.danielt.pestcontrol.AddendumLinInputFragment"
android:id="#+id/addendum1CommentsFragment"
android:layout_below="#+id/txtVAddendum1Date"
android:layout_marginTop="24dp"
tools:layout="#layout/fragment_addendum_lin_input" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add another Addendum Comment"
android:id="#+id/btnAddendumAddComment"
android:layout_below="#+id/scrlVAddendum"
android:layout_centerHorizontal="true"
android:layout_marginTop="36dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save / Update Comments"
android:id="#+id/btnAddendumSave"
android:layout_below="#+id/btnAddendumAddComment"
android:layout_centerHorizontal="true"
android:layout_marginTop="44dp" />
</LinearLayout>
</ScrollView>
I havent added the fragment code but I will if someone wants to see it.
Thanks for any help.
You don't need fragment to hold only comment view. Just inflate new comment view and add it to the parent view.
LayoutInflater inflater = LayoutInflater.from(context);
View inflatedLayout= inflater.inflate(R.layout.yourLayout, container, false);
container.addView(inflatedLayout);
Where container is a view that hold all comments.
Regarding adding fragments, according to Fragments documentation:
If you're adding multiple fragments to the same container, then the
order in which you add them determines the order they appear in the
view hierarchy
Therefore if it's behave different, it could be related to OS version or bug :)
My application (min level 13) is an Activity that uses tabs in the action bar to manage a couple fragments, very similar to this.
Now, the activity starts a service which does continuous computation and returns values which I would like to display in the Fragments. The Activity - Service communication is implemented through broadcast receivers and the Activity shuffles the data off to the appropriate Fragment.
Everything seems setup correctly and the data makes it to the Fragment update method but when I try to display the new values in textviews, the new values are never displayed.
The code to change the textviews:
TextView tv = (TextView) getView().findViewById(R.id.fieldNavGpsTime);
Double doub = input.getDoubleExtra("com.some.thing.GPS_TIME", -1.0);
tv.setText(doub.toString());
The code to call the Fragments update methods from the broadcast receiver in the Activity:
NavigationGuiFragment navfrag = (NavigationGuiFragment) getFragmentManager().findFragmentByTag("navigation");
if (navfrag != null && navfrag.isResumed())
navfrag.UpdateNavUI(intent);
I've noticed that isVisible() doesn't seem to ever return true, but I'm not sure what it means or how to change it.
Additionally, I can't seem to add an imageview to a Fragment programmatically. Here's the code (which resides in onActivityCreated()):
this.compass = new BasicCompass(getActivity());
LinearLayout ll = (LinearLayout) getView().findViewById(R.id.nav_hrztl_lnly);
ll.addView(this.compass);
The BasicCompass constructor takes a Context, admittedly I'm not completely sure what I'm passing in is correct.
The code for this was more or less taken from a working Activity and dropped into a Fragment to allow for tabs. I'm open to suggestion in regards to changing the structure of the code.
Thanks for any help.
EDIT
The xml layout of the Fragment:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/nav_hrztl_lnly"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:focusable="true"
android:focusableInTouchMode="true"
android:baselineAligned="false" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="600dp"
android:layout_height="fill_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true" >
<EditText
android:id="#+id/labelNavGpsTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/gps_time" />
<EditText
android:id="#+id/fieldNavGpsTime"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_3_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavLatitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/latitude" />
<EditText
android:id="#+id/fieldNavLatitude"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavLongitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/longitude" />
<EditText
android:id="#+id/fieldNavLongitude"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavAltitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/altitude" />
<EditText
android:id="#+id/fieldNavAltitude"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_3_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavRoll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/roll" />
<EditText
android:id="#+id/fieldNavRoll"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavPitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/pitch" />
<EditText
android:id="#+id/fieldNavPitch"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavAzimuth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/azimuth_heading" />
<EditText
android:id="#+id/fieldNavAzimuth"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<LinearLayout
android:id="#+id/nav_rdbtn_lnly"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RadioButton
android:id="#+id/rdbtnNavGpsAvailability"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/gps_avail" />
<RadioButton
android:id="#+id/rdbtnNavZuptStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/zupt_stat" />
</LinearLayout>
</LinearLayout>
And the Fragment that uses it:
public class NavigationGuiFragment extends Fragment
{
private RadioButton gpsRdBtn;
private RadioButton zuptRdBtn;
private BasicCompass compass;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View fragview = inflater.inflate(R.layout.navigation_fragment, container, false);
// sets up the rose image that serves as a compass in the GUI
this.compass = new BasicCompass(getActivity());
LinearLayout ll = (LinearLayout) fragview.findViewById(R.id.nav_hrztl_lnly);
ll.addView(this.compass);
return fragview;
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
getActivity().setContentView(R.layout.navigation_fragment);
//Initialize the radio buttons
gpsRdBtn = (RadioButton) getView().findViewById(R.id.rdbtnNavGpsAvailability);
gpsRdBtn.setChecked(false);
zuptRdBtn = (RadioButton) getView().findViewById(R.id.rdbtnNavZuptStatus);
zuptRdBtn.setChecked(false);
}
#Override
public void onResume()
{
super.onResume();
if (!IsMyServiceRunning())
{
gpsRdBtn.setChecked(false);
zuptRdBtn.setChecked(false);
}
}
public void UpdateNavUI(Intent input)
{
TextView tv = (TextView) getView().findViewById(R.id.fieldNavGpsTime);
Double doub = input.getDoubleExtra("com.some.thing.GPS_TIME", -1.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavLatitude);
doub = input.getDoubleExtra("com.some.thing.LATITUDE", 100000.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavLongitude);
doub = input.getDoubleExtra("com.some.thing.LONGITUDE", 100000.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavAltitude);
doub = input.getDoubleExtra("com.some.thing.ALTITUDE", -1.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavRoll);
doub = input.getDoubleExtra("com.some.androidndk.ROLL", 361.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavPitch);
doub = input.getDoubleExtra("com.some.thing.PITCH", 361.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavAzimuth);
doub = input.getDoubleExtra("com.some.thing.AZIMUTH", 361.0);
tv.setText(doub.toString());
this.compass.SetDirection(doub.floatValue());
boolean bool = input.getBooleanExtra("com.some.thing.ZUPT_STATUS", false);
zuptRdBtn.setChecked(bool);
UpdateGpsIndicator(input);
}
public void UpdateGpsIndicator(Intent input)
{
boolean bool = input.getBooleanExtra("com.some.thing.GPS_ON", false);
gpsRdBtn.setChecked(bool);
}
private boolean IsMyServiceRunning()
{
ActivityManager manager = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
{
if ("com.some.thing.Service".equals(service.service.getClassName()))
return true;
}
return false;
}
}
this line:
getActivity().setContentView(R.layout.navigation_fragment);
should be called in Activity.onCreate() and make sure it is just called once. In your code it will be called every time Fragment moves to active state. And the TextView and RaidoButton stuff will be reset to state define in the layout xml.
Checkout Fragment lifecycle here.
UPDATE:
Some view widget's state will be kept by Activity, e.g TextView. Try move your setXXX() method to onResume(). I have experience that setXXX() is not working in onActivityCreated() but works well in onResume().