so i'm creating an android app using Xamarin.android and i'm using the navigation drawer app. I added a fragment and within the fragment I added a button. now I need to handle some events of this button. I tried adding a click event function in the fragment.cs code but I got an exception "System.NullReferenceException: 'Object reference not set to an instance of an object.'". how am I supposed to handle the event?
this is the code of my main activity where I access my fragment when choosing the camera icon option:
Fragment1 fragment = new Fragment1();
public bool OnNavigationItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.nav_camera)
{
SupportFragmentManager.BeginTransaction()
.Replace(Resource.Id.mainFrame, fragment )
.Commit();
}
and this is my fragment's xml code:
<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:text="hi"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="25px"
android:minHeight="25px"
android:id="#+id/textView1" />
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/button1" />
</LinearLayout>
and this is my fragment's c# code where I try to access the button:
public class Fragment1 : Android.Support.V4.App.Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
base.OnCreate(savedInstanceState);
var view = inflater.Inflate(Resource.Layout.fragment1, container, false);
Button bulogin = View.FindViewById<Button>(Resource.Id.button1);
bulogin.Click += Bulogin_Click;
// return base.OnCreateView(inflater, container, savedInstanceState);
return view;
}
private void Bulogin_Click(object sender, EventArgs e)
{
TextView txt = View.FindViewById<TextView>(Resource.Id.textView1);
txt.Text = "bye";
}
}
Related
so I created a listview that has 5 textviews in each row. the last textview is supposed to get me information about certain items upon being clicked. my listview's adapter has a context that corresponds to a fragment.
List<itemproperties> items;
itemdisplay context;
public homeadapter(itemdisplay context, List<itemproperties> items)
: base()
{
this.context = context;
this.items = items;
}
where itemdisplay is a fragment. and this is the code where I try to navigate to a new fragment when clicking on the textview
TextView textView = view.FindViewById<TextView>(Resource.Id.textView5);
Fragment1 fragment = new Fragment1();
if (!textView.HasOnClickListeners)
{
textView.Click += (o, e) =>
{
SupportFragmentManager.BeginTransaction()
.Replace(Resource.Id.mainFrame, fragment)
.Commit();
};
}
all of the above codes are in my adapter. but I get an error because SupportFragmentManager doesn't seem to exist in adapters I guess. so my question is, how am I supposed to do this?
thanks a lot in advance.
Do you want to achieve the result like following GIF?
If so, you Adatper need a mainActivity attribute in constructor, then use following way in GetView method.
class MyAdapter : BaseAdapter<string>
{
private MainActivity mainActivity;
private string[] items;
public MyAdapter(MainActivity mainActivity, string[] items)
{
this.mainActivity = mainActivity;
this.items = items;
}
public override string this[int position] => items[position];
public override int Count => items.Length;
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null) // no view to re-use, create new
view = mainActivity.LayoutInflater.Inflate(Resource.Layout.layout1, null);
view.FindViewById<TextView>(Resource.Id.My_textView1).Text = items[position];
TextView textView = view.FindViewById<TextView>(Resource.Id.textView1);
textView.Text = items[position];
if (!textView.HasOnClickListeners)
{
textView.Click += (o, e) =>
{
Fragment1 fragment = new Fragment1();
FragmentTransaction transaction = mainActivity.FragmentManager.BeginTransaction();
transaction.Replace(Resource.Id.FramePage, fragment);
transaction.AddToBackStack("main");
transaction.CommitAllowingStateLoss();
// Toast.MakeText(mainActivity, "click", ToastLength.Short).Show();
};
}
return view;
}
}
}
If you transfer to fragment layout, You found the previous listview stil existed. Please add android:background="?android:windowBackground" in your activity_main.xml and Fragment layout like following code.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="?android:windowBackground"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/FramePage"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="200dp"
android:choiceMode="singleChoice"/>
</FrameLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="?android:windowBackground"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hello World!" />
</LinearLayout>
In my fragment I have material search bar with navigation button(humbugger).
How can I call Navigation Drawer which is in main activity with that humbugger button in my fragment
Do not get how to handle it inside DictionaryFragment
MainActivity:
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
LinearLayout content = (LinearLayout) findViewById(R.id.content);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this,
drawer,
R.string.nav_open_drawer,
R.string.nav_close_drawer){
};
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
DictionaryFragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
materialSearchBar = (MaterialSearchBar) RootView.findViewById(R.id.search_bar);
...
materialSearchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
#Override
public void onButtonClicked(int buttonCode) {
//***HOW TO HANDLE IT HERE?***
//switch (buttonCode) {
// case MaterialSearchBar.BUTTON_NAVIGATION:
// drawer.openDrawer(Gravity.START);
// break;}
}
});
//return RootView;
}
layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/searchBarDividerColor"
tools:context="com.hfad.catchat.DictionaryFragment">
<com.mancj.materialsearchbar.MaterialSearchBar
android:id="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:mt_hint="Search"
app:mt_navIconEnabled="true"
app:mt_speechMode="false" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
</android.support.v7.widget.RecyclerView>
</LinearLayout>
This is what you can try where you want to toggle navigation drawer in your fragment, this way you will have to write a method in activity to do whatever you want to do from your fragment, be sure it is a public method:
((MainActivity)getContext()).toggleDrawer();
in your MainActivity:
public void toggleDrawer(){
//do your stuff
}
Other way is callback aka interface (the preferred one), pass that as a parameter in fragment's constructor and consume that where you want to change drawer's state. Like inside your activity:
Callback callback = new Callback(){
#Override
public void onDrawerStateChanged(){
//do your stuff
}};
new DictionaryFragment(callback);
And inside your fragment you will have to write a constructor to accept that callback and save in a local variable :
public DictionaryFragment() {
}
#SuppressLint("ValidFragment")
public DictionaryFragment(Callback callback) {
this.callback = callback;
}
And use it like :
callback.onDrawerStateChanged();
You can also pass parameters to MainActivity both ways.
I try to add a fragment to an activity and have already looked at the example from Martijn00.
My problem is, that the activity will be displayed but the fragment will not and in debugging mode, the debugger is not running into the fragment's method OnCreateView. So the attribute of the fragment will be used, but not the fragment. I see only my activity with the green background. I am sure I do something wrong, but after 6 hours I do give up and ask you guys for help :)
Fragment:
namespace TopDownTodoList.Mobile.Droid.Views.Fragments{
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
[Register("topdowntodolist.mobile.droid.views.fragments.TodoOverviewFragment")]
public class TodoOverviewFragment : MvxFragment<TodoOverviewViewModel>
{
protected int LayoutId => Resource.Layout.f_todo_overview_fragment;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
this.Init();
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return this.BindingInflate(this.LayoutId, null);
//return inflater.Inflate(this.LayoutId, container, false);
}
public virtual void Init() { }
}}
Activity:
namespace TopDownTodoList.Mobile.Droid.Views{
[Activity(Label = "MainView")]
public class MainView : MvvmCross.Droid.FullFragging.Views.MvxActivity<MainViewModel>
{
protected int LayoutId => Resource.Layout.main_view;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(this.LayoutId);
this.Init();
}
public virtual void Init(){}
}}
App.cs:
protected override void RegisterClasses()
{
RegisterAppStart<TodoOverviewViewModel>();
}
ViewModels:
public class VMName : MvvmCross.Core.ViewModels.MvxViewModel{...}
FragmentLayout (f_todo_overview_fragment):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mvx="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#0000aa"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:gravity="center"/></LinearLayout>
ActivityLayout (main_view):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#aa0000"
android:layout_width="fill_parent"
android:layout_height="fill_parent"><FrameLayout
android:id="#+id/content_frame"
android:background="#00bb00"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" /></LinearLayout>
Your Activity needs to be of the type MvxCachingFragmentCompatActivity or MvxCachingFragmentActivity to support hosting of fragments.
Secondly you need to ignore the normal inflator, and use binding inflate after that:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
return this.BindingInflate(FragmentId, null);
}
I am trying to create tabs inside a fragment. I manage to create tab inside the fragment, but now I want to load different fragment for each tab (fragment1.class and fragment2.class).
Can anybody please suggest how can i load each fragment to their respective tabs?
Below is my main fragment that is holding the tabs.
Thanks a lot!
public class BusFragment extends Fragment {
private TabHost mTabHost;
View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_bus, container, false);
mTabHost = (TabHost) rootView.findViewById(R.id.tabHost);
mTabHost.setup();
TabHost.TabSpec spec = mTabHost.newTabSpec("tag");
spec.setIndicator("Fragment1");
spec.setContent(new TabHost.TabContentFactory() {
#Override
public View createTabContent(String tag) {
// TODO Auto-generated method stub
return (new AnalogClock(getActivity()));
}
});
mTabHost.addTab(spec);
spec = mTabHost.newTabSpec("tag1");
spec.setIndicator("Fragment2");
spec.setContent(new TabHost.TabContentFactory() {
#Override
public View createTabContent(String tag) {
// TODO Auto-generated method stub
return (new AnalogClock(getActivity()));
}
});
mTabHost.addTab(spec);
spec = mTabHost.newTabSpec("tag2");
spec.setIndicator("Fragment3");
spec.setContent(new TabHost.TabContentFactory() {
#Override
public View createTabContent(String tag) {
// TODO Auto-generated method stub
return (new AnalogClock(getActivity()));
}
});
mTabHost.addTab(spec);
return rootView;
}
}
Hello If you want to load the fragment inside the fragment android provide the Child Fragment Manager instead of ordinary fragment manager. I had the same issue I had the fragment inside that tab when click on tab want to load the different fragments. see the below steps hope will help you.
Step 1. See I have StatisticsFragment with it layout fragment_statistics.
public class StatisticsFragment extends Fragment {
private FragmentTabHost mTabHost;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_statistics,container, false);
mTabHost = (FragmentTabHost) rootView.findViewById(R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(),R.id.tabFrameLayout);
mTabHost.addTab(mTabHost.newTabSpec("WEEK").setIndicator(buildTabLayout(EnumStatistics.WEEKLY)),WeekFragment_.class, null);
mTabHost.addTab(mTabHost.newTabSpec("ALL").setIndicator(buildTabLayout(EnumStatistics.ALL)),DetailedFragment_.class, null);
mTabHost.getTabWidget().getChildAt(0).setOnClickListener(new WeekTabClick());
mTabHost.getTabWidget().getChildAt(1).setOnClickListener(new AllTabClick());
return rootView;
}
#Override
public void onResume() {
super.onResume();
}
private View buildTabLayout(EnumStatistics enumStatistics) {
View tab;
if (enumStatistics == EnumStatistics.WEEKLY) {
tab = getActivity().getLayoutInflater().inflate(R.layout.tab_week_layout, null);
} else if (enumStatistics == EnumStatistics.MONTHLY) {
tab = getActivity().getLayoutInflater().inflate(R.layout.tab_month_layout, null);
} else if (enumStatistics == EnumStatistics.YEAR) {
tab = getActivity().getLayoutInflater().inflate(R.layout.tab_year_layout, null);
} else {
tab = getActivity().getLayoutInflater().inflate(R.layout.tab_detailed_layout, null);
}
return tab;
}
public class WeekTabClick implements View.OnClickListener {
#Override
public void onClick(View v) {
mTabHost.getTabWidget().focusCurrentTab(0);
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
ft.replace(R.id.tabFrameLayout, WeekFragment_.instantiate(getActivity(), WeekFragment_.class.getName()));
ft.addToBackStack(null);
ft.commit();
}
}
public class AllTabClick implements View.OnClickListener {
#Override
public void onClick(View v) {
mTabHost.getTabWidget().focusCurrentTab(1);
FragmentTransaction ft = getChildFragmentManager()
.beginTransaction();
ft.replace(R.id.tabFrameLayout, DetailedFragment_.instantiate(
getActivity(), DetailedFragment_.class.getName()));
ft.addToBackStack(null);
ft.commit();
}
}
}
In above buildTabLayout function intent to build the custom layout of tab widget you can put simple text or image that you want to show inside the tab widget.
Steps 2. fragment_statistics.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:relaxis="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.app.FragmentTabHost
android:id="#+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/croutonview"
android:gravity="center" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
/>
<FrameLayout
android:id="#+id/tabFrameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
</RelativeLayout>
As you see in the above inside the layout tabFrameLayout we load the all child fragment Programmaticly.
Let me know if you have any question and doubt. thank you
I have this listview and it's coded in a fragment class. When selecting a listview item it goes to another fragment and displays the details . But it takes several seconds to load the data because the data i display is using AsyncTask,so it takes some time to get data from the JSON and display . So i need to use a progressBar when an item is clicked in the listview and it should close when the data is ready to display. How can i do this? I referred several tutorials and tried many of them. But i couldn't accomplish what i'm looking for.Hope some of you can help me.
NewsFragment class
private ListView listView;
private ArrayList<BaseElement> News;
private LazyAdapter adapter;
private Activity activity;
private CommonVariable commonVariable;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.news_fragment, container,
false);
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
listView = (ListView) view.findViewById(R.id.list);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id){
android.support.v4.app.Fragment detail = new NewsDetailFragment();
android.support.v4.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().add(R.id.content_frame, detail).addToBackStack("back").commit();
}
});
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
News = JSONServices.getNewsDescription();
return null;
}
#Override
/* check again */
protected void onPostExecute(Void result) {
commonVariable.setNewsDescription(News);
adapter = new LazyAdapter(News, activity,Element.NEWS_LIST.getType());
listView.setAdapter(adapter);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
}
}
NewsDetailFragment
public class NewsDetailFragment extends Fragment {
private View view1;
private ArrayList<BaseElement> newsdetail;
private LazyAdapter adapter;
private Activity activity;
private CommonVariable commonVariable;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newsdetail_fragment, container,
false);
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
view1 = (View) view.findViewById(R.id.list);
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
newsdetail = JSONServices.getNewsDescription();
return null;
}
#SuppressWarnings("unchecked")
#Override
/* check again */
protected void onPostExecute(Void result) {
commonVariable.setTheater(newsdetail);
adapter = new LazyAdapter(newsdetail, activity,Element.NEWS_DETAIL.getType());
((AdapterView<ListAdapter>) view1).setAdapter(adapter);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
}
}
NewsList layout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/grey"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#drawable/listview" >
<ImageView
android:id="#+id/thumb_image"
android:layout_width="150dp"
android:layout_height="120dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
/>
<TextView
android:id="#+id/news_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:layout_toRightOf="#+id/thumb_image"
android:layout_marginTop="10dp"
android:layout_marginLeft="7dp"
android:textStyle="bold"
android:textSize="20dp" />
<!-- <TextView
android:id="#+id/news_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textStyle="bold"
android:layout_below="#+id/news_title"
android:textSize="15dp" /> -->
</LinearLayout>
</RelativeLayout>
NewsFragment layout
<?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"
android:background="#color/grey" >
<!-- <GridView
android:id="#+id/gridView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:numColumns="2"
android:stretchMode="columnWidth"
android:layout_margin="5dp"
android:columnWidth="100dp"/> -->
<ListView
android:id="#+id/list"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:dividerHeight="10dp"
android:layout_margin="6dp">
</ListView>
</LinearLayout>
Add ProgressBar to your NewsFragment layout:
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:indeterminate="true"
android:visibility="gone" />
Then in onItemClick method change it's visibility to true progressBar.setVisibility(View.VISIBLE) to show it and change it's visibility to false to hide it progressBar.setVisibility(View.GONE) in onPostExecute of AsyncTask.
Ok i got it now. I modified my 2nd fragment like this. When an item in the listview is clicked it goes to my second class.So i added a progressBar to my second class and it worked!
public class NewsDetailFragment extends Fragment {
private View view1;
private ArrayList<BaseElement> newsdetail;
private LazyAdapter adapter;
private Activity activity;
private CommonVariable commonVariable;
private ProgressDialog dialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newsdetail_fragment, container,
false);
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
view1 = (View) view.findViewById(R.id.list);
dialog = new ProgressDialog(NewsDetailFragment.this.getActivity());
dialog.setMessage("Loading News");
dialog.setCancelable(true);
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
newsdetail = JSONServices.getNewsDescription();
return null;
}
#SuppressWarnings("unchecked")
#Override
/* check again */
protected void onPostExecute(Void result) {
commonVariable.setTheater(newsdetail);
adapter = new LazyAdapter(newsdetail, activity,Element.NEWS_DETAIL.getType());
((AdapterView<ListAdapter>) view1).setAdapter(adapter);
dialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
dialog.show();
super.onPreExecute();
}
}
}