I am attempting to learn Android Studios using the free Udemy course "Learn Android Application Development." I am on lesson 44 "Fragments Part 1." I am unable to get through the lesson because of an error. I have spent two days and ~8 hours trying to figure it out. Please help me!
The goal of the lesson is to create an app that has a list on one side of the screen and the details on the other. When the user clicks one of the list items, the details are displayed on a textview on the other side of the screen.
The instructor guides us through creating two fragments (ListFrag and DetailFrag) and adding them to the main activity side-by-side. He goes through setting up the list fragment (ListFrag) and passing the clicked list item's index to the main activity. All of that works.
DetailFrag contains a TextView (tvDescription). The instructor sets up the textview and changes the value from the main activity using the index from ListFrag. When running the app, it crashes when you click a list item.
There is one error - '#layout/activity_main' does not contain a declaration with id 'tvDescription'. The issue is in MainActivity.java, tvDescriptions = findViewById(R.id.tvDescription);.
Please help. Thanks in advance for your replies.
XML Files:
activity_main.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-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/listFrag"
android:name="com.example.fragmentvideorev2.ListFrag"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#layout/fragment_list" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/detailFrag"
android:name="com.example.fragmentvideorev2.DetailFrag"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
tools:layout="#layout/fragment_detail" />
</LinearLayout>
fragment_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ListFrag">
<ListView
android:id="#+id/lvList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
fragment_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/teal_700"
tools:context=".DetailFrag">
<TextView
android:id="#+id/tvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:text="TextView"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</LinearLayout>
Java Files:
MainActivity.java
package com.example.fragmentvideorev2;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import android.os.Bundle;
import android.widget.TextView;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements ListFrag.ItemSelected {
TextView tvDescriptions;
ArrayList<String> descriptions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvDescriptions = findViewById(R.id.tvDescription);
ArrayList<String> descriptions = new ArrayList<String>();
descriptions.add("Description for item 1");
descriptions.add("Description for item 2");
descriptions.add("Description for item 3");
}
#Override
public void onItemSelected(int index) {
tvDescriptions.setText(descriptions.get(index));
}
}
ListFrag.java
package com.example.fragmentvideorev2;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.ListFragment;
import androidx.lifecycle.LifecycleObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class ListFrag extends ListFragment {
ItemSelected activity;
public interface ItemSelected
{
void onItemSelected(int index);
}
public ListFrag() {
// Required empty public constructor
}
//called when frag associated with activity, context is activity
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
activity = (ItemSelected) context;
}
//called when oncreate is finished
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<String> data = new ArrayList<String>();
data.add("1. This is one");
data.add("2. This is two");
data.add("3. This is three");
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_expandable_list_item_1, data));
}
//value list get clicked, know posiiton
#Override
public void onListItemClick(#NonNull ListView l, #NonNull View v, int position, long id) {
activity.onItemSelected(position);
}
}
DetailFrag.java - unchanged after creation
package com.example.fragmentvideorev2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import org.w3c.dom.Text;
public class DetailFrag extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public DetailFrag() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment DetailFrag.
*/
// TODO: Rename and change types and number of parameters
public static DetailFrag newInstance(String param1, String param2) {
DetailFrag fragment = new DetailFrag();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_detail, container, false);
}
}
Your code is close. It is because DetailFrag is not yet created when you define your TextView in onCreate() of MainActivity. You can refer Fragment lifecycle with respect to it's activity to know more about the lifecycle of Fragment.
So there are two ways you can change your code:
The first way is to remove definition of your TextView variable and directly call findViewById() in the onItemSelected() callback:
package com.example.fragmentvideorev2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements ListFrag.ItemSelected {
ArrayList<String> descriptions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> descriptions = new ArrayList<String>();
descriptions.add("Description for item 1");
descriptions.add("Description for item 2");
descriptions.add("Description for item 3");
}
#Override
public void onItemSelected(int index) {
// Directly retrieve the TextView here
((TextView) findViewById(R.id.tvDescription)).setText(descriptions.get(index));
}
}
The second way is to move the definition of your TextView in onStart() of MainActivity. That guarantees your DetailFrag is created and hence MainActivity can obtain the View from DetailFrag there:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements ListFrag.ItemSelected {
ArrayList<String> descriptions;
TextView tvDescription;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> descriptions = new ArrayList<String>();
descriptions.add("Description for item 1");
descriptions.add("Description for item 2");
descriptions.add("Description for item 3");
}
#Override
protected void onStart() {
super.onStart();
// Move the definition here
tvDescription = findViewById(R.id.tvDescription);
}
#Override
public void onItemSelected(int index) {
tvDescription.setText(descriptions.get(index));
}
}
And also you may have to take a look at the following problem:
You have defined a member variable ArrayList<String> descriptions;. However, you are setting ArrayList to a local variable here:
ArrayList<String> descriptions = new ArrayList<String>();
descriptions.add("Description for item 1");
descriptions.add("Description for item 2");
descriptions.add("Description for item 3");
And your onItemSelected() callback can just access your member variable, which you have not assigned any value to it. Therefore, you should remove the ArrayList<String> like this:
// This will directly assign value to member variable
descriptions = new ArrayList<String>();
descriptions.add("Description for item 1");
descriptions.add("Description for item 2");
descriptions.add("Description for item 3");
Related
I am just trying to inflate a simple fragment for a newsreader project that uses an RSS feed to display news stories. The task is simply to convert the activities to fragments and retain functionality. I have been trying for days to get this to work.
The only goal right now is to get the fragment to inflate and display a test button, a textview and an empty listview. I have checked the fragment XML dozens of times and found no errors. As far as I understand displaying fragment_items in ActivityItems should work. I am performing this inflation exactly as my textbook describes how to inflate a fragment to no avail. I have tried googling every line of the logcat and reading through as many threads as possible and haven't found a solution yet.
ItemsActivity.java
package com.murach.newsreader;
import java.util.ArrayList;
import java.util.HashMap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class ItemsActivity extends Activity {
private RSSFeed feed;
private FileIO io;
private TextView titleTextView;
private ListView itemsListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_items);
io = new FileIO(getApplicationContext());
titleTextView = (TextView) findViewById(R.id.titleTextView);
itemsListView = (ListView) findViewById(R.id.itemsListView);
}
class DownloadFeed extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
io.downloadFile();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.d("News reader", "Feed downloaded");
new ReadFeed().execute();
}
}
class ReadFeed extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
feed = io.readFile();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.d("News reader", "Feed read");
// update the display for the activity
ItemsActivity.this.updateDisplay();
}
}
public void updateDisplay()
{
if (feed == null) {
titleTextView.setText("Unable to get RSS feed");
return;
}
// set the title for the feed
titleTextView.setText(feed.getTitle());
// get the items for the feed
ArrayList<RSSItem> items = feed.getAllItems();
// create a List of Map<String, ?> objects
ArrayList<HashMap<String, String>> data =
new ArrayList<HashMap<String, String>>();
for (RSSItem item : items) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("date", item.getPubDateFormatted());
map.put("title", item.getTitle());
data.add(map);
}
// create the resource, from, and to variables
int resource = R.layout.listview_item;
String[] from = {"date", "title"};
int[] to = {R.id.pubDateTextView, R.id.titleTextView};
// create and set the adapter
SimpleAdapter adapter =
new SimpleAdapter(this, data, resource, from, to);
itemsListView.setAdapter(adapter);
Log.d("News reader", "Feed displayed");
}
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// get the item at the specified position
RSSItem item = feed.getItem(position);
// create an intent
Intent intent = new Intent(this, ItemActivity.class);
intent.putExtra("pubdate", item.getPubDate());
intent.putExtra("title", item.getTitle());
intent.putExtra("description", item.getDescription());
intent.putExtra("link", item.getLink());
this.startActivity(intent);
}
}
activity_items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFAC83"
android:padding="7dp"
android:text="#string/items_title"
android:textSize="22sp" />
<ListView
android:id="#+id/itemsListView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
ItemsFragment.java
package com.murach.newsreader;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
public class ItemsFragment extends Fragment {
private Button testButton;
private TextView titleTextView;
private ListView itemsListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_items, container, false);
testButton = (Button) view.findViewById(R.id.testButton);
titleTextView = (TextView) view.findViewById(R.id.titleTextView);
itemsListView = (ListView) view.findViewById(R.id.itemsListView);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
fragment_items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment android:name="com.murach.newsreader.ItemsFragment"
android:id="#+id/fragment_items"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFAC83"
android:padding="7dp"
android:text="#string/items_title"
android:textSize="22sp" />
<Button
android:id="#+id/testButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST BUTTON" />
<ListView
android:id="#+id/itemsListView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
The logcat
<pre>
at
com.murach.newsreader.ItemsFragment.onCreateView(ItemsFragment.java:25)
at android.app.Fragment.performCreateView(Fragment.java:2522)
at
android.app.FragmentManagerImpl.ensureInflatedFragmentView(FragmentManager.jav
a:1486)
at
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1269)
at
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1481)
at
android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1723)
at
android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3556)
at
android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:186
)
at
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
at
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
02-06 20:45:13.014 4765-4765/? E/AndroidRuntime: at
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1481)
at
android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1723)
at
android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3556)
at
android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:186 )
at
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
at
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
at
android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at
com.murach.newsreader.ItemsFragment.onCreateView(ItemsFragment.java:25)
at android.app.Fragment.performCreateView(Fragment.java:2522)
at
android.app.FragmentManagerImpl.ensureInflatedFragmentView(FragmentManager.jav
a:1486)
at
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1269)
at
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1481)
at
android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1723)
The layoutinflater should just inflate the fragment xml layout and display the test button and the other widgets. I have tried removing all code irrelevant to inflating the fragment and all code/xml relating to the widgets and it still crashes. I have even created a test project with absolutely nothing but an initial activity with a test button and a fragment with a test button and the layoutinflater still won't work.
java & Two.java)
into each fragments there's editext:
One : editText_One
Two : editText_Two
How to save and resotre editText_One (and editText_Two), when i switch between fragments?
I've tried several things after reading tutos, but nothing working well ;(
One.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_one"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="one" />
<EditText
android:layout_width="237dp"
android:layout_height="wrap_content"
android:inputType="date"
android:ems="10"
android:id="#+id/editText_One"
android:text="blabla"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Two.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_one"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TWO" />
<EditText
android:layout_width="237dp"
android:layout_height="wrap_content"
android:inputT`enter code here`ype="date"
android:ems="10"
android:id="#+id/editText_Two"
android:layout_gravity="center_horizontal" />
One.java :
/**
*
*/
package com.example.navigationsubmenu;
/**
* #author info-medios
*
*/
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import java.util.Calendar;
public class One extends Fragment {
// public static final String EXTRA_URL_nommatiere = "url";
EditText editText_one;
// String valeur;
private final String PERSISTENT_VARIABLE_BUNDLE_KEY = "persistentVariable";
public One() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Bundle bundle = new Bundle();
/* Bundle bundle = getActivity().getIntent().getExtras();
Bundle mySavedInstanceState = getArguments();
if (bundle!= null) {// to avoid the NullPointerException
// editText_one.setText("premiere");
String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
editText_one.setText(persistentVariable);
}*/
Bundle extras = getActivity().getIntent().getExtras();
if (extras != null) {
String persistentVariable = extras.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
editText_one.setText(persistentVariable);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.one, container, false);
//Instancier vos composants graphique ici (faƮtes vos findViewById)
editText_one = (EditText) view.findViewById(R.id.editText_One); //getview marche aussi
/* Bundle extras = getActivity().getIntent().getExtras();
if (extras != null) {
valeur = extras.getString(EXTRA_URL_nommatiere); //Affiche le nom matiere
}
else
{
}
editText_one.setText(valeur );*/
return view;
}
#Override
public void onPause() {
super.onPause();
String persistentVariable = editText_one.getText().toString();
Intent intent = new Intent(getActivity(), One.class);
intent.putExtra(persistentVariable, PERSISTENT_VARIABLE_BUNDLE_KEY);
//startActivity(intent);
getArguments().putString(persistentVariable, PERSISTENT_VARIABLE_BUNDLE_KEY);
}
/* #Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle extras = getActivity().getIntent().getExtras();
if (savedInstanceState != null) {
// Restore last state for checked position.
valeur = extras.getString(EXTRA_URL_nommatiere);
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("TEXT", valeur);
}*/
/* #Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.v(TAG, "Inside of onRestoreInstanceState");
valeur = extras.getString(EXTRA_URL_nommatiere);
}*/
}
Can someone can help me please,
many thnaks
First you need to attach the fragments to activity then you can simply define two strings String one ,String two in the activity containing the fragments and assign the value of each editText to diffrent one
i.e
String one=editTextOne.getText.toString();
String two=editTextTwo.getText.toString();
When you have to switch between either activities or fragments, you can use Shared Preferences to store a small amount of datas and retrieve them.
Shared Prefs are small sets of key/value pairs.
Write
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();
Read
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
You can write and read any primitive data types such as Strings using put[Type] and get[Type] methods.
Source codes above come from the official android developer training and belongs to Android.
"is there a way with saveInstanceState ?"
I think this bundle is usefull when one activity is destroyed and created by Screen rotation or resumed after a call, but not when switching between activities and fragments.
But you can try it. I know that views like EditText with id have a built-in saveInstanceState so you do not have to handle it manually.
To switch between fragments you can use activity class scoped properties. You will need to add interfaces to your fragments to allow them to communicate with the activity.
EXAMPLE
The following example shows how to switch between fragments and keep EditText values.
The MainActivity contains a FrameLayout and two buttons. The fragment transaction is done on button click events.
Fragments include an interface to communicate with the activity. Each time the EditText value is changed, the activity's property is updated.
The activity communicates with the fragment to set EditText value right after the transaction.
First of all, here are xml layouts files for the MainActivity, the FragmentA and the FragmentB classes :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="100"
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="morbak.stackoverflow.fragmentcommunication.MainActivity">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:orientation="horizontal"
android:weightSum="100">
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="Fragment A" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="Fragment B" />
</LinearLayout>
</LinearLayout>
activity_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="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/etOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Fragment A content"/>
</LinearLayout>
fragment_a.xml
<?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">
<EditText
android:id="#+id/etTwo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Fragment B content"/>
</LinearLayout>
fragment_b.xml
Then, here are Fragments A and B classes. Source code is self explanatory.
package morbak.stackoverflow.fragmentcommunication;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class FragmentA extends Fragment {
//Views
EditText etOne;
//Fields
String value;
//Listeners
OnFragmentASelectedListener mCallback;
//Context
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate views and layouts
View rootView = inflater.inflate(R.layout.fragment_a, container, false);
etOne = (EditText) rootView.findViewById(R.id.etOne);
//Events
etOne.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//Execute the interface's abstract method
mCallback.onFragmentASelected(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
etOne.setText(value);
return rootView;
}
//Set the fragment's field value
public void setEditText(String newValue) {
value = newValue;
}
//Interface
public interface OnFragmentASelectedListener {
public void onFragmentASelected(String value);
}
//Throws an exception if the activity implements FragmentA.OnFragmentASelectedListener, but not the abstract method
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity;
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnFragmentASelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentASelectedListener");
}
}
}
FragmentA.java
The same work should be done with FragmentB, but you obviously have to search and replace FragmentA to FragmentB and etOne to etTwo.
Finally, here is the MainActivity who handles fragment transactions and uses fragments' listeners :
package morbak.stackoverflow.fragmentcommunication;
import android.content.Context;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements FragmentA.OnFragmentASelectedListener, FragmentB.OnFragmentBSelectedListener {
Button button1;
Button button2;
FragmentTransaction transaction;
FragmentA fragmentA;
FragmentB fragmentB;
String editTextOne;
String editTextTwo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
editTextOne = "";
editTextTwo = "";
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
transaction = getSupportFragmentManager().beginTransaction();
fragmentA = new FragmentA();
transaction.replace(R.id.fragment_container, fragmentA);
transaction.addToBackStack(null);
transaction.commit();
fragmentA.setEditText(editTextOne);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
transaction = getSupportFragmentManager().beginTransaction();
fragmentB = new FragmentB();
transaction.replace(R.id.fragment_container, fragmentB);
transaction.addToBackStack(null);
transaction.commit();
fragmentB.setEditText(editTextTwo);
}
});
}
public void onFragmentASelected(String value) {
editTextOne = value;
}
public void onFragmentBSelected(String value) {
editTextTwo = value;
}
}
MainActivity.java
The setup I have is a main_activity fragment that just has welcome text, and when you tap the start button, it's supposed to switch fragments. Instead of replacing the current fragment, it just overlays it on top of the main_activity fragment and won't allow me to perform the action associated with the new fragment.
Main Activity example
quote_fragment overlapping main activity
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:contextClickable="false"
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="me.alexoladele.quotebook.MainActivity">
<TextView
android:id="#+id/welcome_screen_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="144dp"
android:gravity="center"
android:text="#string/welcome_screen_text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="36sp" />
<Button
android:id="#+id/start_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="47dp"
android:clickable="true"
android:enabled="true"
android:text="#string/start_button" />
</FrameLayout>
ActivityMain.java
package me.alexoladele.quotebook;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
int count = 0;
final QuoteFragment quoteFragment = new QuoteFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button startButton = (Button) findViewById(R.id.start_button);
final TextView welcomeText = (TextView) findViewById(R.id.welcome_screen_text);
if (startButton != null)
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startSecondFragment(); // start your fragment from MainActivity
//startButton.setVisibility(v.GONE);
//welcomeText.setVisibility(v.GONE);
}
});
}
// This method will be in charge of handling your second fragment
private void startSecondFragment() {
android.support.v4.app.FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.replace(R.id.main_activity, quoteFragment)
.commit();
}
}
quote_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/quote_frag"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:contextClickable="true">
<TextView
android:id="#+id/quote"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:text="#string/tap_screen"
android:textColor="#a6a6a6"
android:textSize="26sp" />
<TextView
android:id="#+id/person"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:text="#string/quotist_name"
android:textColor="#585858"
android:textSize="26sp"
android:visibility="visible" />
</FrameLayout>
QuoteFragment.java:
package me.alexoladele.quotebook;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
//import android.support.v4.app.Fragment;
public class QuoteFragment extends android.support.v4.app.Fragment {
int count = 0;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.quote_fragment,container, false);
FrameLayout touch = (FrameLayout) v.findViewById(R.id.main_activity);
final TextView quoteText = (TextView) v.findViewById(R.id.quote);
// Makes quotes array
//region Description
String[] quotes = {
(Quotes go here, but I didn't put them here to save space)
};
//endregion
// Put quotes array into arraylist
final List<String> quoteList = new ArrayList<>(Arrays.asList(quotes));
//
if (touch != null)
touch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (count >= quoteList.size()) {
count = 0;
}
Quote q = new Quote("");
q.setQuote(quoteList.get(count));
quoteText.setText(q.getQuote());
count++;
v.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
});
// Inflate the layout for this fragment
return inflater.inflate(R.layout.quote_fragment, container, false);
}
}
welcome_screen_fragment:
<FrameLayout 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:clickable="true"
tools:context="me.alexoladele.quotebook.WelcomeScreen">
<TextView
android:id="#+id/welcome_screen_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="144dp"
android:gravity="center"
android:text="#string/welcome_screen_text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="36sp" />
<Button
android:id="#+id/start_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="47dp"
android:clickable="true"
android:enabled="true"
android:text="#string/start_button" />
</FrameLayout>
WelcomeScreen.java:
package me.alexoladele.quotebook;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link WelcomeScreen.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link WelcomeScreen#newInstance} factory method to
* create an instance of this fragment.
*/
public class WelcomeScreen extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
//private OnFragmentInteractionListener mListener;
public WelcomeScreen() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment WelcomeScreen.
*/
// TODO: Rename and change types and number of parameters
public static WelcomeScreen newInstance(String param1, String param2) {
WelcomeScreen fragment = new WelcomeScreen();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.welcome_screen_fragment, container, false);
}
/* // TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
*//**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*//*
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}*/
}
Don't replace your top-level view group. Create an empty frame layout inside of the top-level frame layout and use that as the ID to replace.
If you have elements in the main layout you no longer want visible you'll have to hide them (or use a fragment to show them in the first place which will get replaced).
I create a little app with 3 static fragments and a view pager adapter. But what I want is to create Only one kind of fragment and with a button "add" , add other fragment which will be adapted by the view pager.. here is what i have done
FragmentTab1.java ; FragmentTab2 ; FragmentTab3 have the same code
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentTab2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Get the view from fragmenttab2.xml
View view = inflater.inflate(R.layout.fragmenttab2, container, false);
return view;
}
}
here is my MainActivity.java
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends FragmentActivity {
//Button adfg = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the view from activity_main.xml
setContentView(R.layout.activity_main);
// Locate the viewpager in activity_main.xml
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
// Set the ViewPagerAdapter into ViewPager
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
}
}
ViewPagerAdapter.java
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class ViewPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
// Tab Titles
private String tabtitles[] = new String[] { "Tab1", "Tab2", "Tab3" };
Context context;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
switch (position) {
// Open FragmentTab1.java
case 0:
FragmentTab1 fragmenttab1 = new FragmentTab1();
return fragmenttab1;
// Open FragmentTab2.java
case 1:
FragmentTab2 fragmenttab2 = new FragmentTab2();
return fragmenttab2;
// Open FragmentTab3.java
case 2:
FragmentTab3 fragmenttab3 = new FragmentTab3();
return fragmenttab3;
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
return tabtitles[position];
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textColor="#000000" />
</android.support.v4.view.ViewPager>
fragmenttab1.xml ; fragmenttab2.xml ; fragmenttab3.xml has the same code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 1" />
<Button
android:id="#+id/bajou"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ajouter fragment" />
</LinearLayout>
You need to create a method to add the fragment on the subclass of FragmentPagerAdapter, more or less like this :
//use those lists
private List<Fragment> listFragment = new ArrayList<Fragment>();
private List<String> listFragmentTitle = new ArrayList<String>();
private List<Integer> listFragmentIcon = new ArrayList<Integer>();
public void addTab(Fragment fragment,String title, int icon) {
listFragment.add(fragment);
listFragmentTitle.add(title);
listFragmentIcon.add(icon);
}
#Override
public Fragment getItem(int position) {
// TODO Auto-generated method stub
return listFragment.get(position);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return listFragment.size();
}
Then you just need to use it on the subclass of Activity, example :
//create a private method to set a new - dynamic fragment in the ACTIVITY
private Fragment setFragment(int pos)
{
MyFragment myFragment = new MyFragment();
Bundle data = new Bundle();
data.putString("test", "test");
myFragment.setArguments(data);
return myFragment;
}
Finally, add the fragment (for example, inside an onClickListener) :
//INSIDE an onClickListener
pagerAdapter.addTab(setFragment(position), getItem(position).getName(), R.drawable.ic_launcher);
this is my MainActivity.java class #BlazeTama
package com.light.frag;
import com.light.frag.R;
import com.light.frag.ViewPagerAdapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends FragmentActivity implements OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Locate the viewpager in activity_main.xml
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
// Set the ViewPagerAdapter into ViewPager
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
Button ajou = (Button) findViewById(R.id.bajou);
ajou.setOnClickListener(this);
}
private Fragment setFragment(int pos)
{
MyFragment myFragment = new MyFragment();
Bundle data = new Bundle();
data.putString("test", "test");
myFragment.setArguments(data);
return myFragment;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bajou:
ViewPagerAdapter.addTab(setFragment(position), getItem(position).getName(), R.drawable.ic_launcher);
break;
}
}
}
This is the code I did. But it did not work. Please help?
The app itself lets the user enter his/her name on the EditText, he clicks on the button and the TextView will say like for example his name is Sam. "Your name is Sam".
package com.example.myfirstandroidapp;
import java.text.Format.Field;
import java.util.EventListener;
import javax.security.auth.PrivateCredentialPermission;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Build;
import android.provider.ContactsContract.CommonDataKinds.Event;
public class MainActivity extends ActionBarActivity {
EditText nameTextBox;
TextView nameTextView;
Button nameButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null)
{
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
nameTextBox = (EditText)findViewById(R.id.nameTextBox);
nameTextView = (TextView)findViewById(R.id.nameTextView);
nameButton = (Button)findViewById(R.id.nameButton);
nameButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Clicker();
}
});
}
public void Clicker()
{
if (nameTextBox.getText().toString() != "")
{
nameTextView.setText("Your name is " + nameTextBox.getText().toString());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
Xml layout
<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="com.example.myfirstandroidapp.MainActivity$PlaceholderFragment" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Enter your name:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="#+id/nameTextBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/textView1"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="#+id/nameButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/nameTextBox"
android:layout_below="#+id/nameTextBox"
android:text="I'm Done!" />
<TextView
android:id="#+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/nameButton"
android:layout_below="#+id/nameButton"
android:text="Your name has not been entered yet"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Replace
nameTextBox.getText().toString() != ""
with
!nameTextBox.getText().toString().equals("")
Probably this is your error.
Just Change your code by below code :
package com.example.myfirstandroidapp;
import java.text.Format.Field;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Build;
public class MainActivity extends Activity {
EditText nameTextBox;
TextView nameTextView;
Button nameButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nameTextBox = (EditText)findViewById(R.id.nameTextBox);
nameTextView = (TextView)findViewById(R.id.nameTextView);
nameButton = (Button)findViewById(R.id.nameButton);
nameButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Clicker();
}
});
}
public void Clicker()
{
if (!nameTextBox.getText().toString().equals(""))
{
nameTextView.setText("Your name is " + nameTextBox.getText().toString());
}
}
}
As per your need there is not any requirement of fragments.
Your error probably is that this should be inside onCreateView() in your PlaceHolderFragment rather than in activity
nameTextBox = (EditText)findViewById(R.id.nameTextBox);
nameTextView = (TextView)findViewById(R.id.nameTextView);
nameButton = (Button)findViewById(R.id.nameButton);
In your layout nameTextBox,nameTextBox,nameButton are null,because those are part of fragment not activity_main.
So either use nameTextBox,nameTextBox,nameButton in activity_main layout. or use in onCreateView method of fragment.
For more info see Access Fragment View from Activity's onCreate
The lifecycle of a Fragment is tied to that of its host activity. For example the onActivityCreate() method of a Fragment is called after the host Activity calls its own onCreate method. You are getting an error because you are trying to access View objects that are contained within your Fragment layout from within your activity. This creates a problem because (1) those views do not exist yet at the time the host Activity calls onCreate() because the fragment has yet to be created; (2) findViewById() only searches within the contentView of Activity or Fragment that it is called from (i.e. if you look for a view that is within your Fragment's layout from within the host activity it findViewById will return null becuase the view is not within the Activity's layout).
What you need to do is move the code from your activity's onCreate method to your fragment. You can put this in either onActivityCreated or onViewCreated within your fragment and should access and set content from within the fragment itself. If you need access to the fragment contents you can keep a reference to the fragment within your hosting activity and access public methods within your fragment class.
You should set things up like this
public class PlaceholderFragment1 extends Fragment{
private EditText mNameTextBox;
private TextView mNameTextView;
private Button mNameButton;
public void onActivityCreate(Bundle savedInstanceState){
mNameTextBox = (EditText)findViewById(R.id.nameTextBox);
mNameTextView = (TextView)findViewById(R.id.nameTextView);
mNameButton = (Button)findViewById(R.id.nameButton);
mNameButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mNameTextBox.getText().toString().isEmpty()){
mNameTextView.setText(
"Your name is "+mNameTextBox.getText().toString());
}
});
}
}
I adapted your dropbox code to fix the issues you mentioned.