I looked at existing posts with the same error but code/implementation is different to mine, however the suggestions in some of the posts has not helped to resolve the issue. I am trying to replace a fragment which displays grid (list of images) with another fragment upon an image click. I see the error "Java.lang.UnsupportedOperationException: addView(View) is not supported in AdapterView" during runtime but couldn't make out which part of the code is resulting in this error and what needs to be done to fix this issue. Appreciate your help to resolve this. Code is as below:
Fragment with grid (list of images):
public class OneFragment extends Fragment {
public OneFragment() {
// Required empty public constructor
}
private ListView mListView;
GridView grid;
String[] web = {"Doctors","Dentists","Test" };
int[] imageId = {R.mipmap.doctors,R.mipmap.dentists,R.mipmap.ic_launcher};
#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_one, container, false);
int iconSize=getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
CustomGrid adapter = new CustomGrid(view.getContext(), iconSize);
GridView gridview = (GridView) view.findViewById(R.id.grid);
gridview.setAdapter(adapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(view.getContext(), "You Clicked at " +web[+ position], Toast.LENGTH_SHORT).show();
Log.d("MyApp", "I am here");
//setContentView(R.layout.list_item_main);
ListItemMainFragment nextFrag = new ListItemMainFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.grid, nextFrag);
ft.setTransition(FragmentTransaction.TRANSIT_NONE);// it will anim while calling fragment.
ft.addToBackStack(null); // it will manage back stack of fragments.
ft.commit();
}
});
return view;
}
}
Fragment Resource file:
<GridView
android:numColumns="auto_fit"
android:gravity="center"
android:columnWidth="100dp"
android:stretchMode="columnWidth"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/grid"
/>
</RelativeLayout>
Fragment for Replacement:
public class ListItemMainFragment extends Fragment implements Item.DataListener {
private ListView mListView;
public ListItemMainFragment() {
// Required empty public constructor
}
#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.list_item_main, container, false);
mListView = (ListView) view.findViewById(R.id.item_list_view);
//final String DBReference = "all/" + position + "/" + web[+position];
final String DBReference = "all/0/Doctors";
Item.getRecipesFromDB(ListItemMainFragment.this, DBReference);
return view;
}
#Override
public void newDataReceived(ArrayList<Item> itemList) {
ItemAdapter adapter = new ItemAdapter(mListView.getContext(), itemList);
mListView.setAdapter(adapter);
}
}
Item List Resource file:
<ListView
android:id="#+id/item_list_view"
android:layout_height="match_parent"
android:layout_width="match_parent">
</ListView>
Do this inside your Fragment Resource file where your grid view is, add an id called content(or any other name) to your Relative layout like thisandroid:id="#+id/content" then in the code where your are doing your fragment replacement, edit this line of code ft.replace(R.id.grid, nextFrag); to be ft.replace(R.id.content, nextFrag);. I was in the same dilemma, this worked for me.
<RelativeLayout>
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/content"
<GridView
android:numColumns="auto_fit"
android:gravity="center"
android:columnWidth="100dp"
android:stretchMode="columnWidth"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/grid" />
</RelativeLayout>
Java code class OneFragment
ListItemMainFragment nextFrag = new ListItemMainFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content, nextFrag);
ft.setTransition(FragmentTransaction.TRANSIT_NONE);// it will anim while calling fragment.
ft.addToBackStack(null); // it will manage back stack of fragments.
ft.commit();
Related
I've seen this questioned asked a number of times on here without an answer. I'm hoping if I ask it again maybe someone will be kind enough to help me with it.
I'm trying to implement a shared transition from an Item in a Recyclerview to a fragment.
I currently have my fragment transaction in the onBindView method of the adapter.
public void onClick(View v) {
...
activity.getSupportFragmentMnager().beginTransaction()
.addSharedElement(v, "SharedString")
.replace(R.id.container, fragment2)
.addToBackStack(null)
.commit();
}
In the android docs, addSharedElement(view and string) confuse me. How do I give the view a unique ID and should I even be using v here?
Can the string be what ever I want?
here is my implementation. There is FragmentList with RecyclerView with images on each item. And there is FragmentDetail with only on big image. Image from FragmentList list item fly to FragmentDetail. TransitionName of animated view on FragmentList and FragmentDetail must be same. So I give unique transition name for each list item ImageView:
imageView.setTransitionName("anyString" + position)
Then I pass that string to FragmentDetail via setArguments and set big image transitionName to that string. Also we should provide Transition which describes how view from one view hierarchy animates to another viewhierarchy. After that we should pass that transition to fragment. I do it before FragmentTransaction:
detailFragment.setSharedElementEnterTransition(getTransition());
detailFragment.setSharedElementReturnTransition(getTransition());
Or you can override getSharedElementEnterTransition and getSharedElementReturnTransition of Fragment and declare transition there. Here is full code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, new FragmentList())
.commit();
}
}
public void showDetail(View view) {
String transitionName = view.getTransitionName();
FragmentDetail fragment = new FragmentDetail();
fragment.setArguments(FragmentDetail.getBundle(transitionName));
fragment.setSharedElementEnterTransition(getTransition());
fragment.setSharedElementReturnTransition(getTransition());
getSupportFragmentManager()
.beginTransaction()
.addSharedElement(view, transitionName)
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
private Transition getTransition() {
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_TOGETHER);
set.addTransition(new ChangeBounds());
set.addTransition(new ChangeImageTransform());
set.addTransition(new ChangeTransform());
return set;
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
FragmentList:
public class FragmentList extends Fragment {
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_list, container, false);
RecyclerView rv = view.findViewById(R.id.recyclerview);
rv.setAdapter(new ListAdapter());
return view;
}
private class ListAdapter extends RecyclerView.Adapter {
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Holder hold = (Holder) holder;
hold.itemView.setOnClickListener(v -> {
((MainActivity) getActivity()).showDetail(hold.imageView);
});
//unique string for each list item
hold.imageView.setTransitionName("anyString" + position);
}
#Override
public int getItemCount() {
return 10;
}
private class Holder extends ViewHolder {
ImageView imageView;
public Holder(View view) {
super(view);
imageView = view.findViewById(R.id.image);
}
}
}
}
fragment_list.xml
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
FragmentDetail:
public class FragmentDetail extends Fragment {
private static final String NAME_KEY = "key";
public static Bundle getBundle(String transitionName) {
Bundle args = new Bundle();
args.putString(NAME_KEY, transitionName);
return args;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_detail, container, false);
String transitionName = getArguments().getString(NAME_KEY);
ImageView imageView = view.findViewById(R.id.image);
imageView.setTransitionName(transitionName);
return view;
}
}
fragment_detail.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#+id/image"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="#drawable/cat"/>
</LinearLayout>
item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/cat"/>
</LinearLayout>
Here is result:
TransitionName may be any string you want.
There is ViewCompat.setTransitionName if you need support pre Lollipop devices.
Adding to the ashakirov's answer:
Problem
Return Transition was not working!
Reason:
On popbackstack from Fragment B to Fragment A, Fragment A's onCreateView is called and if your data is still loading then the return transition won't work with only ashakirov's code.
Solution
Postpone the transition in your fragments
Add this line where the loading starts in your fragment A:
postponeEnterTransition();
After your data is loaded or you've set your adapter, write this:
startPostponedEnterTransition();
This ensures that your transition only happens after your data is loaded.
Also, make sure you start the transition even in 'data failed to load scenarios'.
If you want to postpone the transition in your fragment B when going from A to B then add this to your fragment B:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//hold the transition
postponeEnterTransition();
//when the views are available then start the transition
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
Im studying about fragments and Im doing a basic example but its not working.
I have a basic example where I have 2 activities:
- One activity with a image and a textview and when the image is clicked I go to another activity that that has a list view with some items. When this list view is clicked I go back to the main activity and in the textview I show the text associated with the list item clicked.
But Now Im trying to pass this basic example but using fragments with only one activity, but its not working it appears always “app has stopped” when the image is clicked.
What Im doing, and I don’t know if its the best solution, is have the main activity just with the image that needs to be clicked so that it appears the fragment with the list view. And having 2 fragments, one to show the list view and another to show the textview with the text of the clicked item.
For now im just doing the first part, that is click on the image and show the fragment with the list view and when the item on the fragment is clicked show a message with toast. But its not working, it appears always “app has “stopped”.
So what I have is, in the main activity:
public class MainActivity extends AppCompatActivity {
private ImageView img;
private TextView tv;
Intent intent;
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
img = (ImageView) findViewById(R.id.imageView);
tv = (TextView) findViewById(R.id.textView);
}
public void AddFragmentList(View view) {
Fragment fragment = new Fragment();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.listviewInFragment, fragment, "frag");
transaction.commit();
}
}
main activity xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/image"
android:onClick="AddFragmentList"
tools:layout_editor_absoluteY="71dp"
tools:layout_editor_absoluteX="0dp" />
<FrameLayout
android:layout_width="0dp"
android:layout_height="11dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="110dp">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
In fragment java:
public class fragment extends Fragment {
private ListView listItems;
private String[] items = {
"item1",
"item2",
"item3",
"item4"
};
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listItems = (ListView) listItems.findViewById(R.id.listviewInFragment);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_1, android.R.id.text1, items);
listItems.setAdapter(adapter);
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int positionCode = i;
String clickedValue = (String) listItems.getItemAtPosition(positionCode);
Listener listener = (Listener) getActivity();
listener.addText(clickedValue);
Toast.makeText(getActivity().getApplicationContext(), clickedValue, Toast.LENGTH_SHORT).show();
}
});
}
}
And in fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0ff">
<ListView
android:layout_width="368dp"
android:layout_height="495dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="16dp"
android:id="#+id/listviewInFragment"/>
</android.support.constraint.ConstraintLayout>
Have a id for FrameLayout
<FrameLayout
andorid:id="#+id/container"
android:layout_width="0dp"
Then change
transaction.add(R.id.listviewInFragment, fragment, "frag");
to
transaction.add(R.id.container, new fragment(), "frag");
Finally change this
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int positionCode = i;
String clickedValue = (String) listItems.getItemAtPosition(positionCode);
Listener listener = (Listener) getActivity();
listener.addText(clickedValue);
Toast.makeText(getActivity().getApplicationContext(), clickedValue, Toast.LENGTH_SHORT).show();
}
to
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String clickedValue = (String) adapterView.getItemAtPosition(i);
Toast.makeText(getActivity().getApplicationContext(), clickedValue, Toast.LENGTH_SHORT).show();
}
Besides you can have interface as a callbaclk to the activity. Not sure what you are doing with Listener listener = (Listener) getActivity();listener.addText(clickedValue);
This should help https://developer.android.com/training/basics/fragments/communicating.html
I am doing a sample project as an excercise and want to display two fragments in the same activity when dealing with tablets(7' and 10').
So what I have so far is this.
As you can see I can display the data of my recyclerview in the left (static) fragment. However the right fragment is empty.
So I have two questions.
1) How to display by default in the right fragment the data of the first row of recyclerview?(ie image and article)
2) How to implement the click listener and update the right fragment?
Here is my code:
MainActivity
public class MainActivity extends AppCompatActivity {
private boolean mTwoPane;
private static final String DETAIL_FRAGMENT_TAG = "DFTAG";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(findViewById(R.id.detailed_match_reports)!=null) {
mTwoPane = true;
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.detailed_match_reports, new DetailedActivityFragment(),DETAIL_FRAGMENT_TAG)
.commit();
}else{
mTwoPane = false;
}
}
}
}
layout/activity_main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/match_reports"
android:name="theo.testing.androidservices.fragments.MainActivityFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
tools:context="theo.testing.androidservices.activities.MainActivity"
tools:layout="#android:layout/list_content" />
layout-sw600dp/activity_main
<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:baselineAligned="false"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
tools:context="theo.testing.androidservices.activities.MainActivity">
<fragment
android:id="#+id/match_reports"
android:name="theo.testing.androidservices.fragments.MainActivityFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
tools:layout="#android:layout/list_content" />
<FrameLayout
android:id="#+id/detailed_match_reports"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4" />
</LinearLayout>
MainActivityFragment
public class MainActivityFragment extends Fragment {
public static final String TAG = "AelApp";
public static ArrayList<MyModel> listItemsList;
RecyclerView myList;
public static MatchReportsAdapter adapter;
public MainActivityFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
updateMatchReport();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
getActivity().setTitle("Match Report");
View rootView = inflater.inflate(R.layout.fragment_main_activity, container, false);
listItemsList = new ArrayList<>();
myList = (RecyclerView)rootView.findViewById(R.id.listview_match_reports);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
myList.setHasFixedSize(true);
myList.setLayoutManager(linearLayoutManager);
adapter = new MatchReportsAdapter(getActivity(), listItemsList);
myList.setAdapter(adapter);
return rootView;
}
public void updateMatchReport(){
Intent i = new Intent(getActivity(), MatchReport.class);
getActivity().startService(i);
}
}
First let me answer the second question. To show a fragment on the right side of the screen add something like this (note how I'm using that id of the frame layout to replace the fragment):
Fragment fragment = new MyRightSideFragment();
FragmentManager fm = getFragmentManager();
fm.beginTransaction().replace(R.id.detailed_match_reports, fragment).commit();
Now, for the first question, you need to implement click listener, you can find an example here.
public class ReactiveAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = (Integer)v.getTag();
showDetail(position);
}
});
}
}
Notice that I'm using the tag of the view to identify the position (so somwhere in your onBindViewHolder code you must set this tag).
public function showDetail(int position) {
... show fragment por position
}
and finally, when your in your OnCreateView or somewhere in your setup code, call showDetail(0).
I've been creating News application. I used this tutorial to create good-looking Navigation Drawer. It uses fragments for every category in Navigation List. I will be using provided API to get news (in the JSON format), and i need customized List View to show the list of news. When you click list item, it will open new view to show details of news. I've found several tutorials, but none of them worked for fragment. Please, tell me way to do it.
I'm new to Android Programming. This is my first project, though it is too hard for being first project. But i have to do it. Please, help!
Thanks beforehand!
Assuming you know how to create an adapter and a custom row layout from a tutorial that works for activities. Minor modifications will help you using fragments.
Your fragment should look like this:
public class NewFragment extends Fragment{
CustomAdapter listAdapter;
ListView listView;
ArrayList<Data> yourData; // Should be filled with data from your JSONParser;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
/*
* Use your custom adapter. in this example the adapter need
* the context and an array that contains your data
*/
listAdapter = new CustomAdapter(getActivity(),yourData);
...
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.new_fragment, container, false);
listView = (LsitView)view.findViewById(R.id.your_list);
listView.setAdapter(listAdapter);
...
}
}
You can use for this ListFragment:
Here is a fully customized example:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="#+id/frameLayout"/>
</RelativeLayout>
mylist.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">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
</LinearLayout>
myitem.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">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:id="#+id/txt_mytext" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment fr = mListFragment.newInstance();
FragmentManager fm = getFragmentManager();
fm.beginTransaction().add(R.id.frameLayout, fr, "tag").commit();
}
}
mListFragment.java
public class mListFragment extends ListFragment {
public static mListFragment newInstance() {
mListFragment f = new mListFragment();
//Bundle args = new Bundle();
//f.setArguments(args);
return f;
}
public mListFragment() {}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String[] strings = {"a", "b", "c"};
ArrayAdapter<String> adapter = new LstAdapter(
getActivity(), R.layout.myitem,
strings);
setListAdapter(adapter);
return inflater.inflate(R.layout.mylist, null);
}
public class LstAdapter extends ArrayAdapter<String> {
private String[] mArray;
public LstAdapter(Context context, int textViewResourceId, String[] mList) {
super(context, textViewResourceId, mList);
mArray = mList;
}
#Override
public int getCount() {
return mArray.length;
}
#Override
public String getItem(int position) {
return mArray[position];
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.myitem, null);
}
TextView tvName = (TextView) v.findViewById(R.id.txt_mytext);
tvName.setText(mArray[position]);
return v;
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.d("123", position + "");
super.onListItemClick(l, v, position, id);
}
}
I've got a FragmentActivity which show the correct fragment, using a ViewPager. I added a Fragment StatePagerAdapter to the ViewPager. If I push a button at a Fragment, it should be recreated (onCreateView should be called again). The fragments are articles and if the user is offline, I'll show him "please check your networkconnection" and a button to reload. The button called a method in the FragmentActivity, but I don't know how implement it. Maybe I can destroy and recreate the current Fragment?
here the important part of the FragmentActivity:
private ArrayList<Fragment> fragments;
protected void onCreate(Bundle savedInstanceState)
{
context = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_article_page_slider);
...
pages = datahandler.getCount(...);
viewPager = (ViewPager) findViewById(R.id.articlePager);
PagerAdapter pagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(startPosition);
fragments = new ArrayList<Fragment>(pages);
}
public void reloadData(View v)
{
// TODO
((ArticlePageFragment)fragments.get(viewPager.getCurrentItem())).refresh();
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
Fragment fragment = new ArticlePageFragment();
Bundle args = new Bundle();
...
fragment.setArguments(args);
fragments.add(position, fragment);
return fragment;
}
public int getCount()
{
return pages;
}
}
and the Fragment itself:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
activity = getActivity();
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_article_page, container, false);
CacheDataHandler cdh = new CacheDataHandler(activity);
cdh.open();
String htmlData = cdh.loadData();
rootView.findViewById(R.id.btn_reload_article_data).setVisibility(View.GONE);
webView = ((WebView) rootView.findViewById(R.id.articleFragment));
refresh();
...
return rootView;
}
public void refresh()
{
...
if (htmlData == null)
{
rootView.findViewById(R.id.btn_reload_article_data).setVisibility(View.VISIBLE);
webView.loadData(defaultdata,"text/html", "UTF-8");
}
else
{
webView.loadData(htmlData,"text/html", "UTF-8");
}
}
and the fragment_article_page.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<WebView
android:id="#+id/articleFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:id="#+id/btn_reload_article_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:onClick="reloadData"
android:text="#string/btn_txt_reload_data"
android:visibility="gone" />
</RelativeLayout>
EDIT
added a private ArrayList<Fragment> fragments in FragmentActivity and transfer the code for manipulating the view in an extra refreshMethod, look ahead. All works fine, if I only click on the first or second Fragment (index 0 and 1). Otherwise I get an IndexOutOfBoundsException. How to initialize and fill the ArrayList?