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.
Related
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");
I'm following Android Fundamentals CodeLabs (https://developer.android.com/codelabs/android-training-create-recycler-view?index=..%2F..%2Fandroid-training#3), with minor changes given I am using a more advanced version of Android Studio (4.1.1) and am getting a null recyclerView in MainActivity onCreate method even though the view exists. I've used BasicActivity to start this project. How do I fix this?
Here my XML for fragment_first.xml:
<?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"
tools:context=".FirstFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/ourcards_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
and here the MainActivity.java file content:
package com.example.ourcards;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import java.util.LinkedList;
public class MainActivity extends AppCompatActivity {
private final LinkedList<String> mCardList = new LinkedList<>();
private RecyclerView mRecyclerView;
private CardListAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
mCardList.addLast("Carta 1");
mCardList.addLast("Carta 2");
// Get a handle to the RecyclerView.
mRecyclerView = findViewById(R.id.ourcards_view);
// Create an adapter and supply the data to be displayed.
mAdapter = new CardListAdapter(this, mCardList);
// Connect the adapter with the RecyclerView.
mRecyclerView.setAdapter(mAdapter);
// Give the RecyclerView a default layout manager.
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
EDIT
Here is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.OurCards.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/Theme.OurCards.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#drawable/ic_add_for_fab" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here content_main.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here my CardListAdapter.java
package com.example.ourcards;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.LinkedList;
public class CardListAdapter extends
RecyclerView.Adapter<CardListAdapter.CardViewHolder> {
private final LinkedList<String> mCardList;
private final LayoutInflater mInflater;
class CardViewHolder extends RecyclerView.ViewHolder {
public final TextView cardItemView;
final CardListAdapter mAdapter;
public CardViewHolder(View itemView, CardListAdapter adapter) {
super(itemView);
cardItemView = itemView.findViewById(R.id.card);
this.mAdapter = adapter;
}
}
public CardListAdapter(Context context,
LinkedList<String> cardList) {
mInflater = LayoutInflater.from(context);
this.mCardList = cardList;
}
#NonNull
#Override
public CardListAdapter.CardViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View mItemView = mInflater.inflate(R.layout.cardlist_item,
parent, false);
return new CardViewHolder(mItemView, this);
}
#Override
public void onBindViewHolder(#NonNull CardListAdapter.CardViewHolder holder, int position) {
String mCurrent = mCardList.get(position);
holder.cardItemView.setText(mCurrent);
}
#Override
public int getItemCount() {
return mCardList.size();
}
}
and here my FirstFragment.java
package com.example.ourcards;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
public class FirstFragment extends Fragment {
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false);
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
}
}
Here my XML for fragment_first.xml:
Note that your filename is fragment_first.xml.
and here the MainActivity.java file content
Your code here seems to have nothing to do with fragment_first.xml. For example, your setContentView() call is loading activity_main.xml.
So, either your RecyclerView needs to be in activity_main.xml, your setContentView() needs to be loading fragment_first, or you otherwise need to synchronize the work in your two code snippets.
This question already has answers here:
Explanation of ClassCastException in Java
(12 answers)
Closed 4 years ago.
Here is my problem. Below is my class (Events.java) below it is the error. I continue to run my code on my phone but continue to get that error. I don't know what exactly the problem is and I don't know how to fix it. I tried everything I looked up but kept getting errors. Please help I'm a noob obviously.
package com.androidapp.restart;
import android.app.Fragment;
import android.app.LoaderManager;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import com.getbase.floatingactionbutton.FloatingActionButton;
/**
* Created by aa215995 on 3/2/2018.
*/
public class Events extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private FloatingActionButton mAddEventButton;
private Toolbar mToolbar;
EventCursorAdapter mCursorAdapter;
EventDbHelper eventDbHelper = new EventDbHelper(getActivity());
ListView eventListView;
ProgressDialog prgDialog;
private static final int VEHICLE_LOADER = 0;
#Nullable
#Override
public ListView onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
eventListView = (ListView) inflater.inflate(R.layout.nav_events, container, false);
mToolbar = (Toolbar) getView().findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);
mToolbar.setTitle("Events");
eventListView = (ListView) getView().findViewById(R.id.list);
View emptyView = getView().findViewById(R.id.empty_view);
eventListView.setEmptyView(emptyView);
mCursorAdapter = new EventCursorAdapter(getActivity(), null);
eventListView.setAdapter(mCursorAdapter);
eventListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Intent intent = new Intent(view.getContext(), AddEvent.class);
Uri currentVehicleUri = ContentUris.withAppendedId(EventContract.EventEntry.CONTENT_URI, id);
// Set the URI on the data field of the intent
intent.setData(currentVehicleUri);
startActivity(intent);
}
});
mAddEventButton = (FloatingActionButton) getView().findViewById(R.id.fab);
mAddEventButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), AddEvent.class);
startActivity(intent);
}
});
getLoaderManager().initLoader(VEHICLE_LOADER, null, this);
return eventListView;
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String[] projection = {
EventContract.EventEntry._ID,
EventContract.EventEntry.KEY_TITLE,
EventContract.EventEntry.KEY_DATE,
EventContract.EventEntry.KEY_TIME,
EventContract.EventEntry.KEY_REPEAT,
EventContract.EventEntry.KEY_REPEAT_NO,
EventContract.EventEntry.KEY_REPEAT_TYPE,
EventContract.EventEntry.KEY_ACTIVE
};
return new CursorLoader(getActivity(), // Parent activity context
EventContract.EventEntry.CONTENT_URI, // Provider content URI to query
projection, // Columns to include in the resulting Cursor
null, // No selection clause
null, // No selection arguments
null); // Default sort order
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mCursorAdapter.swapCursor(cursor);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
mCursorAdapter.swapCursor(null);
}
}
This is the error
05-24 14:02:00.885 15627-15627/com.androidapp.restart E/AndroidRuntime:
FATAL EXCEPTION: main
Process: com.androidapp.restart, PID: 15627
java.lang.ClassCastException: android.widget.LinearLayout cannot be cast
to android.widget.ListView
at com.androidapp.restart.Events.onCreateView(Events.java:47)
at com.androidapp.restart.Events.onCreateView(Events.java:31)
at android.app.Fragment.performCreateView(Fragment.java:2508)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1279)
at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2407)
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2186)
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2142)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2043)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:719)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
This is the xml file (events.xml)
<?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/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.androidapp.restart.Events">
<ListView
android:id="#+id/list"
android:layout_below="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<TextView
android:id="#+id/no_event_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="16dp"
android:gravity="center"
android:text="#string/no_cardetails"/>
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="16dp"
android:src="#drawable/ic_add_black_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
EDITED
Now I have change the xml to a Relative Layout, same issues, but here is another issue I found:
at android.app.Fragment.performCreateView(Fragment.java:2508)
Here is the section of the Fragment.java:
if (mFragmentManager != null) {
writer.print(prefix); writer.print("mFragmentManager=");
writer.println(mFragmentManager);
}
This is an issue:
eventListView = (ListView) inflater.inflate(R.layout.nav_events, container, false);
You try to inflate listview but inflater returns you a LinearLayout a parent of all views. You need inflate the LinearLayout instead of listview and this is causes to cast exception.
You are trying to cast a layout on a listview
add this #id into your LinearLayout and inflate it in your Activity
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#id/layout";
tools:context="com.delaroystudiuos.alarmreminder.MainActivity">
and then call it like this
LinearLayout ll = (LinearLayout) inflater.inflate(R.layout.layout, container, false);;
If you are trying to access your existing ListView item in the XML:
<ListView
android:id="#+id/list"
android:layout_below="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
You will need to instead use:
View view = inflater.inflate(R.layout.nav_events, container, false);
eventListView = view.findViewById(R.id.list);
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
How can I add fragments for each tab in BottomBar in Android studio please a good example like list view or grid view for each tab..thanks
You need to implement SetOnTabSelectListerner.
bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
#Override
public void onTabSelected(#IdRes int tabId) {
Fragment fragment = null;
Class fragmentClass = null;
switch (tabId) {
case R.id.tab_one:
fragmentClass = TabOneFragment.class;
break;
case R.id.tab_two:
fragmentClass = TabTwoFragment.class;
break;
case R.id.tab_three:
fragmentClass = TabThreeFragment.class;
break;
case R.id.tab_four:
fragmentClass = TabFourFragment.class;
break;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
}
});
main_activity.java
import android.app.Activity;
import android.app.FragmentManager;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity implements communicator{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void respond(int i) {
android.support.v4.app.FragmentManager fm=getSupportFragmentManager();
FragmentB f2= (FragmentB)fm.findFragmentById(R.id.fragment2);
f2.changedata(i);
}
}
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.widget.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:background="#00BBFF"
android:orientation="vertical"
tools:context="com.example.dhanya.myfragmentexample.MainActivity">
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/fragment"
android:name="com.example.dhanya.myfragmentexample.FragmentA"
/>
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment2"
android:name="com.example.dhanya.myfragmentexample.FragmentB"
/>
</android.widget.LinearLayout>
fragmentA.java
package com.example.dhanya.myfragmentexample;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class FragmentA extends Fragment implements AdapterView.OnItemClickListener{
ListView list;
communicator comm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
comm= (communicator) getActivity();
list=(ListView)getActivity().findViewById(R.id.lv);
ArrayAdapter ad=ArrayAdapter.createFromResource(getActivity(),R.array.listval,android.R.layout.simple_list_item_1);
list.setAdapter(ad);
list.setOnItemClickListener(this);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView txt=(TextView)view;
String str=txt.getText().toString();
comm.respond(position);
}
}
fragmentA.xml
<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"
tools:context="com.example.dhanya.myfragmentexample.FragmentA"
android:background="#FFBB00">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lv"/>
</FrameLayout>
fragmentB.java
package com.example.dhanya.myfragmentexample;
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentB extends Fragment {
TextView txt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_fragment_b, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
txt=(TextView)getActivity().findViewById(R.id.textv);
}
public void changedata(int i)
{
Resources res=getResources();
String[] des=res.getStringArray(R.array.desciptions);
// String str=Integer.toString(i);
txt.setText(des[i]);
// txt.setText(str); }}
fragmentB.xml
<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"
tools:context="com.example.dhanya.myfragmentexample.FragmentB"
android:background="#99CC00"
>
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textv"/>
</FrameLayout>
strings.xml
<resources>
<string name="app_name">MyFragmentExample</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string-array name="listval">
<item>fragments</item>
<item>Activities</item>
<item>Services</item>
<item>Content Providers</item>
</string-array>
<string-array name="desciptions">
<item>A Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a "sub activity" that you can reuse in different activities).</item>
<item>Activities are one of the fundamental building blocks of apps on the Android platform. They serve as the entry point for a user's interaction with an app, and are also central to how a user navigates within an app (as with the Back button) or between apps (as with the Recents button). </item>
<item>A Service is an application component that can perform long-running operations in the background, and it does not provide a user interface. Another application component can start a service, and it continues to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service can handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.</item>
<item>Content providers can help an application manage access to data stored by itself, stored by other apps, and provide a way to share data with other apps. They encapsulate the data, and provide mechanisms for defining data security. Content providers are the standard interface that connects data in one process with code running in another process. Implementing a content provider has many advantages. </item>
</string-array>
</resources>
communicator.java
public interface communicator {
public void respond(int i);
}
//Grid view
main_activity.xml
<ScrollView xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="#+id/gridview1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="50dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth" >
</GridView>
</RelativeLayout>
</ScrollView>
mainactivity.java
package com.example.harish.mylayoutexamples;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;
public class GridActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
GridView gridView;
static final String[] numbers = new String[] {
"A", "B", "C", "D", "E",
"F", "G", "H", "I", "J",
"K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid);
gridView = (GridView) findViewById(R.id.gridview1);
// Create adapter to set value for grid view
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, numbers);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(this);
/* gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(getApplicationContext(),
((TextView) v).getText() , Toast.LENGTH_SHORT).show();
}
});*/
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(),
((TextView) view).getText() , Toast.LENGTH_SHORT).show();
}
}
fragments dynamic loading
Main activity. Java
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Button firstFragment, secondFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get the reference of Button's
firstFragment = (Button) findViewById(R.id.firstFragment);
secondFragment = (Button) findViewById(R.id.secondFragment);
// perform setOnClickListener event on First Button
firstFragment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// load First Fragment
loadFragment(new FirstFragment());
}
});
// perform setOnClickListener event on Second Button
secondFragment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// load Second Fragment
loadFragment(new SecondFragment());
}
});
}
private void loadFragment(Fragment fragment) {
// create a FragmentManager
FragmentManager fm = getFragmentManager();
// android.support.v4.app.FragmentManager fm=getSupportFragmentManager();
// create a FragmentTransaction to begin the transaction and replace the Fragment
FragmentTransaction fragmentTransaction = fm.beginTransaction();
// replace the FrameLayout with new Fragment
fragmentTransaction.replace(R.id.frameLayout, fragment);
//fragmentTransaction.add(R.id.firstFragment,fragment);
fragmentTransaction.commit(); // save the changes
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
MAIN_ACTIVTY.XML
<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: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=".MainActivity">
<!-- display two Button's and a FrameLayout to replace the Fragment's -->
<Button
android:id="#+id/firstFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/button_background_color"
android:text="First Fragment"
android:textColor="#color/white"
android:textSize="20sp" />
<Button
android:id="#+id/secondFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#color/button_background_color"
android:text="Second Fragment"
android:textColor="#color/white"
android:textSize="20sp" />
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp" />
</LinearLayout>
FIRST_FRAGMENT.JAVA
package com.abhiandroid.fragmentexample;
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.Toast;
public class FirstFragment extends Fragment {
View view;
Button firstButton;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_first, container, false);
// get the reference of Button
firstButton = (Button) view.findViewById(R.id.firstButton);
// perform setOnClickListener on first Button
firstButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// display a message by using a Toast
Toast.makeText(getActivity(), "First Fragment", Toast.LENGTH_LONG).show();
}
});
return view;
}
}
FIRST_FRAGMENT>XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.abhiandroid.fragmentexample.FirstFragment">
<!--TextView and Button displayed in First Fragment -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="This is First Fragment"
android:textColor="#color/black"
android:textSize="25sp" />
<Button
android:id="#+id/firstButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#color/green"
android:text="First Fragment"
android:textColor="#color/white"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
SECOND_FRAGMENT>JAVA
package com.abhiandroid.fragmentexample;
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.Toast;
public class SecondFragment extends Fragment {
View view;
Button secondButton;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_second, container, false);
// get the reference of Button
secondButton = (Button) view.findViewById(R.id.secondButton);
// perform setOnClickListener on second Button
secondButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// display a message by using a Toast
Toast.makeText(getActivity(), "Second Fragment", Toast.LENGTH_LONG).show();
}
});
return view;
}
}
SECOND_FRAGMENT>XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.abhiandroid.fragmentexample.SecondFragment">
<!--TextView and Button displayed in Second Fragment -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="This is Second Fragment"
android:textColor="#color/black"
android:textSize="25sp" />
<Button
android:id="#+id/secondButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#color/green"
android:text="Second Fragment"
android:textColor="#color/white"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
main_activity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity implements communicator {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void respond(String i) {
android.support.v4.app.FragmentManager fm=getSupportFragmentManager();
FragmentB f2= (FragmentB)fm.findFragmentById(R.id.fragment2);
f2.changedata(i);
}
}
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.widget.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"
tools:context="com.example.dhanya.myfragmentcommsimple.MainActivity"
android:orientation="vertical">
<fragment
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/fragment"
android:name="com.example.dhanya.myfragmentcommsimple.FragmentA">
</fragment>
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment2"
android:name="com.example.dhanya.myfragmentcommsimple.FragmentB">
</fragment>
</android.widget.LinearLayout>
fragment_A.java
package com.example.dhanya.myfragmentcommsimple;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListView;
public class FragmentA extends Fragment implements View.OnClickListener{
int count=0;
Button bt;
communicator comm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
comm= (communicator) getActivity();
bt=(Button)getActivity().findViewById(R.id.btn);
bt.setOnClickListener(this);
}
#Override
public void onClick(View v) {
count++;
comm.respond("The button is clicked "+ count+" times");
}
}
FRAGMET_A.xml
<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"
tools:context="com.example.dhanya.myfragmentcommsimple.FragmentA"
android:background="#99FF00">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btn"
android:text="counter"
android:layout_margin="40dp"/>
</FrameLayout>
FRAGMENT_B.java
package com.example.dhanya.myfragmentcommsimple;
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentB extends Fragment {
TextView txt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_fragment_b, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
txt=(TextView)getActivity().findViewById(R.id.tv);
}
public void changedata(String i)
{
txt.setText(i);
}
}
FRAGMENT_B.xml
<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"
tools:context="com.example.dhanya.myfragmentcommsimple.FragmentB"
android:background="#FFBB00">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="haiiii"
android:id="#+id/tv"
android:layout_margin="50dp"/>
</FrameLayout>
COMMUNICATOR.java
package com.example.dhanya.myfragmentcommsimple;
public interface communicator {
public void respond(String i);
}