Nullpointer exception while getting EditText in an Activity - android

This is my layout file.
<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"
tools:context=".ImageDownloadActivity" >
<EditText
android:id="#+id/url_text"
android:layout_width = "match_parent"
android:layout_height="wrap_content"
android:hint="#string/url_field_hint"
android:inputType="textUri"
android:layout_alignParentTop="true"/>
<Button
android:id="#+id/download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/download_url"
android:layout_below="#+id/url_text"
android:layout_centerHorizontal="true"
android:onClick="downloadImage"
/>
</RelativeLayout>
And this is my Fragment class
public class ImageDownloadFragment extends Fragment {
public ImageDownloadFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return (RelativeLayout)inflater.inflate(R.layout.image_download, null);
}
}
In an activity I am doing this.
imageDownloadFragment = new ImageDownloadFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.image_download_layout, imageDownloadFragment);
fragmentTransaction.commit();
EditText urlText = (EditText)findViewById(R.id.url_text);
if(urlText!=null)
urlText.setText(urlEntered);
So I have an xml layout. I am inflating that in a Fragment and then I am replacing the fragment in a container. Everything works fine till this point. But after committing the FragmentTransaction, when I try to access the EditText View in the fragment, it gives me the null pointer exception. All the ids are correct in the R file. Please suggest

You should try:
public class ImageDownloadFragment extends Fragment {
private EditText ed;
public ImageDownloadFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.image_download, container, false);
ed = (EditText)v.findViewById(R.id.url_text);
return v;
}
}
Since the EditText you want to retrieve is located (I suppose) inside your Fragment's layout.

Check findViewById returns NULL when using Fragment
In your onCreateView try to use
return (RelativeLayout)inflater.inflate(R.layout.image_download, container, false);
Hope it helps else please comment.

Related

Xamarin Android Get View from Fragment Instance

This is my xml file
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:id="#+id/MainPersonalIDLayout">
<TextView
android:text="Personal ID"
android:textSize="18dp"
android:textColor="#000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:id="#+id/PersonalIDTitle" />
<LinearLayout
android:orientation="horizontal"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:id="#+id/SubPersonalIDLayout">
<TextView
android:text="No ID"
android:textSize="20dp"
android:gravity="center"
android:layout_width="200dp"
android:layout_height="match_parent"
android:id="#+id/PersonalID" />
<Button
android:text="Use this"
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:onClick="UsePersonalID"
android:id="#+id/UsePersonalID" />
</LinearLayout>
</LinearLayout>
This is my Dashboard Fragment
public class DashboardTab : Fragment
{
View DashboardView;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
// return inflater.Inflate(Resource.Layout.YourFragment, container, false);
DashboardView = inflater.Inflate(Resource.Layout.Dashboard, container, false);
return DashboardView;
}
}
And this is my MainActivity.cs, I created an instance of the Dashboard fragment
SetContentView(Resource.Layout.activity_main);
DashboardTab Dashboard = new DashboardTab();
TextView PersonalIDHolder = Dashboard.View.FindViewById<TextView>(Resource.Id.PersonalID);
This is the error that shows when I run
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Is it possible to get the view from an instance of Fragment?
Android get view of fragment in activity
Thank you
Yes, You will get the System.NullReferenceException because you are trying to access the Fragment's View in onCreate Method of activity and till now fragment view is not initialized.
Update your views in OnCreateView method in Fragment
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var DashboardView = inflater.Inflate(Resource.Layout.Dashboard, container, false);
TextView textView = View.FindViewById<TextView>(Resource.Id.PersonalID);
return DashboardView;
}
OR If your changes depend on Activity your fragment is attached to, then you can use OnActivityCreated method of Fragment.
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
TextView textView = View.FindViewById<TextView>(Resource.Id.PersonID);
var act = (MainActivity)Activity;
}
The answer is yes.I don't know how you get instance of your fragment, but there is a way to get a Fragment by FindFragmentByTag.
When you add the Fragment,you could do something like:
SupportFragmentManager
.BeginTransaction()
.Add(Resource.Id.settingsContainer, new DashboardTab() , "DashboardTab")
.Commit();
then get the DashboardTab fragemnt in Activity OnResume() or OnStart() method:
protected override void OnResume()
{
base.OnResume();
DashboardTab Dashboard = SupportFragmentManager.FindFragmentByTag("DashboardTab");
TextView textView = Dashboard.View.FindViewById<TextView>(Resource.Id.PersonalID);
}

fragments overlap in one screen

I am now practicing on ViewPager and Fragments but I am facing an issue with replacing fragment to one another.
It is working well with swiping screen to move to another fragment, but I also wanted to try out if I can do this with a button too.
So I added a button, and tried to use FragmentManager's replace() method.
But what it actually does is not replacing the fragment but adding the fragment on the current fragment.
In a simple word, it overlaps.
Could not really find anything helpful for hours now, can anyone please help me with it?
Here is my code of the fragment that has the button:
public class MainActivity extends Fragment {
Fragment fragment;
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
Button buildButton;
private ViewPager viewPager;
public static Fragment newInstance(Context context) {
MainActivity mainActivity = new MainActivity();
return mainActivity;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.main, null);
return root;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
buildButton = (Button) getView().findViewById(R.id.buildButton);
buildButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
fragment = new SecondActivity();
fragmentManager = getActivity().getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.calendarActivity, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
}
}
And this is the xml file of the fragment:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment class="com.example.auclo.calendarpractice5.MainActivity"
android:id="#+id/calendarActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button
android:id="#+id/buildButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="100dp"
android:layout_marginEnd="148dp"
android:layout_marginStart="148dp"
android:layout_marginTop="16dp"
android:text="Track"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/calendarView" />
</android.support.constraint.ConstraintLayout>
And this is the fragment that I want to replace to:
public class SecondActivity extends Fragment {
TextView textView;
public static Fragment newInstance(Context context) {
SecondActivity secondActivity = new SecondActivity();
return secondActivity;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.activity_second, null);
return root;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
textView = getView().findViewById(R.id.textView);
}
}
And xml of the second fragment:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<fragment class="com.example.auclo.calendarpractice5.SecondActivity"
android:id="#+id/secondActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pikachu"
android:textSize="18sp" />
</RelativeLayout>
I will really appreciate to any kind of help.
Thank you!
The issue is that you're replacing the element with ID calendarActivity with your new fragment. This element is inside the XML for your first fragment (I think, based on your post). So it's putting this fragment in your old fragment.
You'll need to instead use the id in R.layout.main that represents your first fragment. I usually use a framelayout for this. Then I have the activity replace that framelayout with a fragment in its onCreate().
To add the same visual effects, you have to add a animation to your fragmentTransaction
Exemple:
fragmentTransaction.setCuston(
R.anim.enter_from_right,
R.anim.exit_to_left);
See this answer for explanation on fragments animations

Android: Fragment showing from old fragment

I have two fragments on top of each other when I call the second fragment I still the buttons from the first fragment stay visible and functional.
I tried many many methods but didn't work
This one gave me this error:
java.lang.IllegalArgumentException: No view found for id 0x7f0e0004 (*.test:id/customId) for fragment SecondFragment{adef947 #0 id=0x7f0e0004}
and This
java.lang.IllegalArgumentException: No view found for id 0x7f0e00ae (sy.aya.ayaisp.test:id/gatesViewpager) for fragment SecondSFragment{adef947 #0 id=0x7f0e00ae}
my code is as follows:
FirstFragment.java
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.first_fragment, container, false);
Button FBtn = (Button) myView.findViewById(R.id.Fbutton);
FBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString("second", "f button");
SecondFragment secondFragment = new secondFragment();
secondFragment.setArguments(bundle);
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_in_up);
ft.replace(R.id.s_con, secondFragment).addToBackStack("back").commit();
}
});
SecondFrag.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String bundleString = this.getArguments().getString("second");
View view = inflater.inflate(R.layout.s_rv, container, false);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.s_recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
if (bundleString == "agents button") {
recyclerView.setAdapter(new SecondAdapter(getContext()));
}
}
first_fragment.xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/s_con"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/Fbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="secondFragment"/>
</android.support.constraint.ConstraintLayout>
s_rv.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">
<sy.aya.ayaisp.ExpandableRecyclerView
android:id="#+id/s_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:clipToPadding="false"
android:scrollbars="vertical" />
</FrameLayout>
Thank you for your help
In second fragment layout "s_rv" in root element of xml add some background, clickable="true" and focusable="true".
And in first fragment layout wrap your button in LinearLayout. two days back I was also facing same issue it was solved after that.
It is because in your first fragment the id of button is "pos_agents_button" but in findViewById you are trying to find "R.id.Fbutton".
Change
Button FBtn = (Button) myView.findViewById(R.id.Fbutton);
to
Button FBtn = (Button) myView.findViewById(R.id.pos_agents_button);
and everything should work fine.

HorizontalScrollView duplicated view when in ViewPager

I've got HorizontalScrollView inside RelativeLayout on two pages in ViewPager. At first it works ok, but when I swipe through the pages inside ViewPager and then again try to scroll the HorizontalScrollView, the view is duplicated like this:
So it's like duplicated with one view stuck on the background and one on the foreground is scrolling normally.
I've tried several things like play with background color, persistentDrawingCache, removeAllViews and add them again but it still happens.
Can you help me find out what's causing this and how to fix this?
Thanks a lot!
Update: here are the code snippets
horizontal_scrollview_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"
android:overScrollMode="never"
android:persistentDrawingCache="none"
android:layout_centerHorizontal="true" >
<LinearLayout
android:id="#+id/horizontalScrollLinearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</HorizontalScrollView>
horizontal_scrollview_child_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.ursus.nameday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.xxx.CircularImageView
android:id="#+id/contactPhotoImageView"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/ic_launcher"
app:border="true"
app:border_color="#android:color/holo_blue_light"
app:border_width="2dp"
app:shadow="true" />
<TextView
android:id="#+id/contactNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
HorizontalScrollViewFragment.java
public class HorizontalScrollViewFragment extends Fragment {
private LinearLayout childLinearLayout;
#Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
final View rootView = inflater.inflate(
R.layout.horizontal_scrollview_layout, container, false);
contactsLinearLayout = (LinearLayout) rootView
.findViewById(R.id.horizontalScrollLinearLayout);
//ADDING CHILDREN HERE
final View child1 = LayoutInflater.from(getActivity()).inflate(
R.layout.horizontal_scrollview_child_layout, null);
childLinearLayout.addView(child1);
...
return rootView;
}
}
DayViewFragment.java (fragment inserted into ViewPager)
public class DayViewFragment extends Fragment {
...
private HorizontalScrollViewFragment fragment;
#Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.day_item_layout,
container, false);
...
final FragmentManager fm = getChildFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
fragment = new HorizontalScrollViewFragment();
ft.add(R.id.fragmentContainer, fragment);
ft.commit();
...
return rootView;
}
}
The issue occurred when the fragment was recreated after the limit of the screens to be retained by ViewPager was reached and the fragment holding the fragment needed to be recreated.
The default value is 1 therefore I only needed to change it to 2 (setOffscreenPageLimit(2)) as I have 3 fragments in ViewPager. Now the problem doesn't occur.
It's not an ideal solution but works. In case this doesn't help somebody else: you need to control when and how the fragment is recreated and make sure view is cleared.

Switching 2 fragments within one activity - Android

I'm trying to replace one fragment with another following a button click (onClick) event. I'm new to fragments so if I'm going about this the wrong way please let me know.
At run time a frame layout (container) is loaded. A fragment is then added to it dynamically. This works fine. If I add in the setOnClickListener I get a NullPointerException. Here's the Java:
public class WelcomeActivity extends ActionBarActivity {
FrameLayout container;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
//setContentView(R.layout.welcome_fragment);
container = (FrameLayout)findViewById(R.id.mainContainer);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.mainContainer) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
addWelcomeFragment();
}
//NPE at the below line
Button submitUser = (Button) findViewById(R.id.submitUser);
submitUser.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view){
addExpedFragment();
}
});
}
Through researching fragments I'm using static class within the WelcomeActivity class to load the fragments. They are here:
public static class WelcomeFragment extends Fragment {
public static Fragment newInstance(){
Fragment wFrag = new WelcomeFragment();
return wFrag;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.welcome_fragment, null);
return v;
}
}
//-----------------------------------------------------------------------------------------------------//
public static class ExpedFragment extends Fragment {
public static Fragment secondInstance(){
Fragment eFrag = new ExpedFragment();
return eFrag;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.exped_fragment, null);
return v;
}
}
And the methods to invoke these are also with WelcomeActivity here:
private void addWelcomeFragment(){
Fragment welcome = WelcomeFragment.newInstance();
FragmentTransaction fTrans = getSupportFragmentManager().beginTransaction();
fTrans.add(R.id.mainContainer, welcome);
fTrans.addToBackStack(null);
fTrans.commit();
}
private void addExpedFragment(){
Fragment exped = ExpedFragment.secondInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.mainContainer, exped).commit();
}
I have a feeling that the problem is to do with trying to find the button view id "submitUser" from the first fragment. My xmls look like this.
The first empty FrameLayout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/mainContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</FrameLayout>
</RelativeLayout>
The first fragment loaded in at runtime:
<?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:id="#+id/welcome_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:context=".WelcomeActivity" >
<TextView
android:id="#+id/welcome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/welcome1"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="#+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/welcome"
android:layout_alignRight="#+id/welcome"
android:layout_below="#+id/welcome"
android:layout_marginTop="32dp"
android:ems="10"
android:hint="#string/userHint"
android:inputType="textPersonName" >
<requestFocus />
</EditText>
<Button
android:id="#+id/submitUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/userName"
android:layout_alignRight="#+id/userName"
android:layout_below="#+id/userName"
android:layout_marginTop="16dp"
android:text="#string/Done" />
<FrameLayout
android:id="#+id/mainContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</FrameLayout>
</RelativeLayout>
The second fragment to replace the first with the onClick event:
<?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:id="#+id/exped_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:context=".WelcomeActivity" >
<TextView
android:id="#+id/expedText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/exped"
android:textAppearance="?android:attr/textAppearanceLarge">
</TextView>
<FrameLayout
android:id="#+id/mainContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</FrameLayout>
</RelativeLayout>
IF I forget loading the first fragment at runtime and setContentView(first fragment) there is no NullPointerException but the two fragments overlay each other when the button is pressed rather than replacing.
So my question is, how do I reference the active fragment to properly set the OnClickListener and avoid the NullPointerException?
Button submitUser = (Button) findViewById(R.id.submitUser);
gives the NPE
Problem:
Button submitUser = (Button) findViewById(R.id.submitUser);
The submitUser is located in your WelcomeFragment's layout not in your Activity's layout that is why it is null.
solution:
Instead of initializing it in your activity class you need to initialize it within your Welcome fragment view.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.welcome_fragment, null);
Button submitUser = (Button) v.findViewById(R.id.submitUser);
submitUser.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view){
addExpedFragment();
}
});
return v;
}
EDIT:
private void addExpedFragment(){
Fragment exped = ExpedFragment.secondInstance();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainContainer, exped).commit();
}

Categories

Resources