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);
}
Related
I am an Android programming beginner. Appears my problem is simple and silly, still not able to locate the issue.
In the fragment, my objective is to show a dot every second which helps prompting someone to do some physical action, but no way near that. I am moving bit by bit and got struct at the first level itself.
public class ActionFragment extends Fragment {
private FragmentActionBinding binding;
TextView pCycleNum;
int pCycle;
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
View v = inflater.inflate(R.layout.fragment_action, container, false);
pCycleNum = v.findViewById(R.id.pCN);
pCycleNum.setText(String.valueOf(1));
binding = FragmentActionBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(ActionFragment.this)
.navigate(R.id.action_ActionFragment_to_LauncherFragment);
}
});
binding.buttonAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pCycleNum.setText("5");
}
});
}
I am setting pCycleNum to 5. But when I run the app on emmulator, it does not show any change. Not able to find out where I am going wrong.
The fragment xml is as follows
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
android:background="#color/white"
android:foregroundTint="#color/teal_700"
tools:context=".ActionFragment">
<Button
android:id="#+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/teal_200"
android:backgroundTint="#F57F17"
android:text="#string/goback"
android:textColor="#color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.96"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/textview_second"
app:layout_constraintVertical_bias="0.96" />
<TextView
android:id="#+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/teal_700"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/buttonAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="178dp"
android:layout_marginStart="139dp"
android:layout_marginTop="33dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.13"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.97" />
<TextView
android:id="#+id/pCN"
android:layout_width="174dp"
android:layout_height="112dp"
android:layout_marginStart="80dp"
android:layout_marginTop="130dp"
android:text="1"
android:textColor="#color/teal_200"
android:textSize="96sp"
android:visibility="visible"
app:layout_constraintStart_toEndOf="#+id/imageView13"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Please help to me to locate the error why app not displaying the set value. Also help me to understand why it is doing so. Thanks.
Just remove these lines from onCreateView() method.
View v = inflater.inflate(R.layout.fragment_action, container, false);
pCycleNum = v.findViewById(R.id.pCN);
pCycleNum.setText(String.valueOf(1));
And then use binding.pCN.setText("5");
This happened because you are using both findViewById() and view binding simulataneously.
And you are returning the binding in onCreateView() method. And onViewCreated() method don't know from where to get this pCN text view so it just skips.
you got a textview by id from v layout but then inflated a new layout, gave its reference to binding and returned the binding view not the view you used findViewById on
to avoid this mistake afterwards, just get your views from the binding object, you'll find them all by their id names (without any underscore character "_") like I did in binding.pCN
public class ActionFragment extends Fragment {
private FragmentActionBinding binding;
TextView pCycleNum;
int pCycle;
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentActionBinding.inflate(inflater, container, false);
pCycleNum =binding.pCN;
return binding.getRoot();
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(ActionFragment.this)
.navigate(R.id.action_ActionFragment_to_LauncherFragment);
}
});
binding.buttonAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pCycleNum.setText("5");
}
});
}
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();
}
I have a MainActivity.class which extends from Activity . I created a tab like structure . on clicking any of the image . new fragment is displayed. My first fragment is Article. it has a AsyncTask associate with it.
when i go to another fragment and comeback to it .asyncTask call again. And the whole listView is recreated . I simply want to disable AsyncTask for calling again and save the previous state of the fragment.
I have addToBackStack(null); while adding fragments.
getFragmentManager().beginTransaction().replace(R.id.container, new Article()).addToBackStack(null).commit();
where Article is a fragment and container is the frameLayout in the mainActivity.xml
I want to show the fragment where i left off. Like we do in Activities by setting LaunchMode+"Single" or something . I am not clearing backStack.
I simply need to switch between Activities like we do in TabActivity. in TabActivity if we want to repeat the AsyncTask we have to specify it in onResume(). otherwise it will not called
Article Fragment
public class Article extends Fragment
{
ListView listView;
Activity context;
ArrayList<HashMap<String,String>> art_list;
ArticleAdapter adapter;
String url="http://tabletennisdaily.co.uk/webservices/view_articles.php";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View V = inflater.inflate(R.layout.article, container, false);
context = getActivity();
listView = (ListView) V.findViewById(R.id.art_listview);
new ArticleTask(getActivity(), url, listView).execute(url);
return V;
}
}
MainActivity
public class MainActivity extends Activity //implements FragmentDelegate,FragmentManager.OnBackStackChangedListener
{
public LinearLayout Tab1,Tab2,Tab3,Tab4;
public ImageView img1,img2,img3,img4;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.practicing);
init();
}
private void init()
{
Tab1 = (LinearLayout) findViewById(R.id.tab1);
Tab2 = (LinearLayout) findViewById(R.id.tab2);
Tab3 = (LinearLayout) findViewById(R.id.tab3);
Tab4 = (LinearLayout) findViewById(R.id.tab4);
img1 = (ImageView)findViewById(R.id.tab_img1);
img2 = (ImageView)findViewById(R.id.tab_img2);
img3 = (ImageView)findViewById(R.id.tab_img3);
img4 = (ImageView)findViewById(R.id.tab_img4);
getFragmentManager().beginTransaction().replace(R.id.container, new Article()).addToBackStack(null).commit();
}
public void selectFrag(View view) {
Fragment fr = null;
if (view == findViewById(R.id.tab1))
{
img1.setBackgroundResource(R.drawable.articles_on);
img2.setBackgroundResource(R.drawable.forum_off);
img3.setBackgroundResource(R.drawable.video_off);
img4.setBackgroundResource(R.drawable.profile_off);
fr = new Article();
}
else if(view == findViewById(R.id.tab2))
{
img1.setBackgroundResource(R.drawable.articles_off);
img2.setBackgroundResource(R.drawable.forum_on);
img3.setBackgroundResource(R.drawable.video_off);
img4.setBackgroundResource(R.drawable.profile_off);
fr = new Forum();
}
else if(view == findViewById(R.id.tab3))
{
img1.setBackgroundResource(R.drawable.articles_off);
img2.setBackgroundResource(R.drawable.forum_off);
img3.setBackgroundResource(R.drawable.video_on);
img4.setBackgroundResource(R.drawable.profile_off);
fr = new Medias();
}
else if(view == findViewById(R.id.tab4))
{
img1.setBackgroundResource(R.drawable.articles_off);
img2.setBackgroundResource(R.drawable.forum_off);
img3.setBackgroundResource(R.drawable.video_off);
img4.setBackgroundResource(R.drawable.profile_on);
fr = new Profile();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.container, fr);
fragmentTransaction.addToBackStack(null);//MainActivity.TAG);//.addToBackStack(null);
fragmentTransaction.commit();
}
}
and practicing.xml is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainlayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottom" />
<LinearLayout
android:id="#+id/bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<LinearLayout
android:id="#+id/tab1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:onClick="selectFrag"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/tab_img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/articles_on"
android:padding="10dp"
android:scaleType="center" />
</LinearLayout>
<LinearLayout
android:id="#+id/tab2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:onClick="selectFrag"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/tab_img2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/forum_off"
android:padding="10dp"
android:scaleType="center" />
</LinearLayout>
<LinearLayout
android:id="#+id/tab3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:onClick="selectFrag"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/tab_img3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/video_off"
android:padding="10dp"
android:scaleType="fitXY" />
</LinearLayout>
<LinearLayout
android:id="#+id/tab4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:onClick="selectFrag"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/tab_img4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/profile_off"
android:padding="10dp"
android:scaleType="fitXY" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Try adding your fragment instead of replacing.
What addToBackStack() does is: it adds the fragment transaction to its stack, so it knows that when you press back, it should show your first fragment. So t does exactly that, and shows your first fragment again and the fragment's onCreatView() is called again. Here in your onCreateView, all initialization occurs and the AsyncTask is called. This is why it happens everytime you change between fragments.
The solution I implemented for this problem is:
1) Keep view of fragment as a class variable.
2) Perform all actions in onCreateView() only if the view is null.
So you should change:
public class Article extends Fragment
{
ListView listView;
Activity context;
ArrayList<HashMap<String,String>> art_list;
ArticleAdapter adapter;
String url="http://tabletennisdaily.co.uk/webservices/view_articles.php";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View V = inflater.inflate(R.layout.article, container, false);
context = getActivity();
listView = (ListView) V.findViewById(R.id.art_listview);
new ArticleTask(getActivity(), url, listView).execute(url);
return V;
}
}
to:
public class Article extends Fragment
{
ListView listView;
Activity context;
ArrayList<HashMap<String,String>> art_list;
ArticleAdapter adapter;
String url="http://tabletennisdaily.co.uk/webservices/view_articles.php";
View V; //SET THE FRAGMENTS VIEW AS A CLASS VARIABLE HERE
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{ //CHECK IF FRAGMENT IS INSTANTIATED BEFORE. IF IT IS NOT, CREATE NEW VIEW
if(V == null){
V = inflater.inflate(R.layout.article, container, false);
context = getActivity();
listView = (ListView) V.findViewById(R.id.art_listview);
new ArticleTask(getActivity(), url, listView).execute(url);
}
else{ //IF ALREADY INSTANTIATED USE SAME OLD V
((ViewGroup)V.getParent()).removeView(V);
}
return V;
}
}
Here, we move View V outside and make it a class variable. So if it is the first time the fragment is called, it is null and the initialization occurs, otherwise it goes to else black. Else block is required because onCreateView() adds whatever it returns as a child of the view's parent, so since V is already there, we remove it and onCreateView automatically adds it again.
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.
I have a ViewPager which holds multiple base fragments, each base fragment have four more nested fragments and each nested fragment is a combination of 5 imageViews and textView.
(This is what I intended to do)
I have created a sample application but I am not able to implement that properly. I cannot see any view in the nested fragment or the base fragment.
Here's the code for the sample application
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<fragment android:name="com.example.nestedfragments.BaseFragment"
android:id="#+id/left_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
MainActivity.java
package com.example.nestedfragments;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
base_fragment.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:gravity="center">
<Button
android:id="#+id/button1"
android:text="Launch Nested Fragment"
android:gravity="center"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingBottom="10dp"/>
</RelativeLayout>
BaseFragment.java
public class BaseFragment extends Fragment {
Button doNestingButton;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// set the view
View root = inflater.inflate(R.layout.base_fragment, container, false);
doNestingButton = (Button) root.findViewById(R.id.button1);
doNestingButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment videoFragment = new NestedFragment();
// we get the 'childFragmentManager' for our transaction
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
// make the back button return to the main screen
// and supply the tag 'left' to the backstack
transaction.addToBackStack("left");
// add our new nested fragment
transaction.add(getId(), videoFragment, "left");
// commit the transaction
transaction.commit();
}
});
return root;
}
}
nested_fragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="154dp"
android:layout_height="154dp"
android:id="#+id/imageView" android:layout_gravity="left|center_vertical"
android:src="#drawable/ic_splash"/>
</LinearLayout>
NestedFragment.java
public class NestedFragment extends Fragment {
public NestedFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.nested_fragment, container, false);
ImageView doNestingButton = (ImageView) root.findViewById(R.id.imageView);
return root;
}
Once again this is a sample application, please guide me.
From your above code, you have not used the fragment container layout such as FrameLayout in base_fragment.xml .So add the frame layout for nested fragment inbase_fragment.xml