I've a listview in an activity and I want to open a fragment when an item is clicked. For that I used FrameLayout along with ListView but it causes overlapping of fragment class over the activity. Is there any way to remove this solution?
Activity's Listview Item Click code:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
DetailsView details = new DetailsView();
getSupportFragmentManager().beginTransaction().addToBackStack(null).add(R.id.frame, details).commit();
}
});
activity layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.baoyz.swipemenulistview.SwipeMenuListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</RelativeLayout>
Try to use FragmentManager.Replace() instead of .add()
Related
The code is working fine in Main activity. How to extend this spinner class to all the activities in my project?
The items of spinner are only visible if I add spinner entries in XML
Moreover, There is no call to onItemSelected. I have followed every tutorial possible But couldn't figure out how to do it.
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:entries="#array/MenuItems" />
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:entries="#array/MenuItems" />
No item is added programmatically.
public class MainMenu extends Activity implements OnItemSelectedListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = (Spinner)findViewById(R.id.spinner1);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, getResources().getStringArray(R.array.MenuItems));
spinner.setAdapter(spinnerAdapter);
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String item = adapterView.getItemAtPosition(i).toString();
// Showing selected spinner item
Toast.makeText(adapterView.getContext(), "Selected: " + item, Toast.LENGTH_LONG).show();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
My activity_main is as follows
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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="com.example.supreetkaur.pocbeacon.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:background="?attr/colorPrimary" >
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:entries="#array/MenuItems" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
I am a beginner in Android Development. Would really appreciate any help.
im trying to use setContentView to switch to a layout with a fragment inside it
but it crashes every time
what should i do?
this is my entire code:
(it must switch to fragment_layout when i click the button in the activity_main)
(fragmant_layout has a fragment and the layout for the frgment is te layout1)
(it crashs when i cick the button to switch)
main activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void switchlayout(View view) {//when the button in clicked
setContentView(R.layout.fragment_layout);
}
}
the fragment class:
public class frgment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout1,container,false);
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".fragmenttest.MainActivity">
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="switchlayout"
android:layout_marginTop="74dp"
android:id="#+id/button" />
</RelativeLayout>
fragment_layout.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:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="alirezamellat.fragmenttest.frgment"
></fragment>
</LinearLayout>
layout1.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">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorAccent"></View>
</LinearLayout>
Please consider the following points::
On your parent layout (activity_main.xml), inside the Relative layout, add another layout called FrameLayout.
On your fragment layout(fragment_layout.xml), remove the fragment and add the layouts of layout1.xml to fragment_layout.xml
On your fragment class (MyFragment), inflate the fragment_layout.xml to the container and return the view (class name should start with uppercase letter, so name it like MyFragment)
On Activity class, place the following code on onclick listener.
//onClick on OnClickListener
MyFragment fragment = new MyFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.frame_layout, fragment)
.commit();
Once the layout of an Activity has been set it can not be changed at a later time.
There are a number of ways you can achieve this from which the easiest would be to have a wrapper layout and then injecting the fragment inside it using the FragmentManager class.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragmenttest.MainActivity">
<FrameLayout
android:id="#+id/wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="switchlayout"
android:layout_marginTop="74dp"
android:id="#+id/button" />
</RelativeLayout>
And then on your button click add your fragment.
getSupportFragmentManager().beginTransaction().add(R.id.wrapper, MyFragment.newInstance(), "FragTag").commit();
Remember that you have to take care of your button since it will still be visible on top of you fragment.
I have RecyclerView inside ScrollView which is inside SwipeRefresh layout. I have few layouts on top of RecyclerView, but my RecyclerView is not visible, even if i remove other layouts from ScrollView. What do you suggest? I need to put list below some layouts in ScrollView somehow.
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<include layout="#layout/toolbar"></include>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
....
<android.support.v7.widget.RecyclerView
android:id="#+id/simpleList"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
Tried to give specific height but still not visible o.O
If i replace RecyclerView with ListView, then list is visible.
If you want to have all the items of the list always visible then replace RecyclerView with LinearLayout and add your items to it.
An example:
your_layout.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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<include layout="#layout/toolbar"></include>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
....
<LinearLayout
android:id="#+id/simpleList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/item_text"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/abc_ic_ab_back_mtrl_am_alpha"/>
</LinearLayout>
And in your Java code:
first declare the list
mSimpleList = (LinearLayout) findViewById(R.id.simpleList);
then method for adding the items
public void addListItems(ArrayList<String> strings) {
LayoutInflater inflater = LayoutInflater.from(this);
for(String s : strings) {
View item = inflater.inflate(R.layout.item_layout, mSimpleList, false);
TextView text = (TextView) item.findViewById(R.id.item_text);
text.setText(s);
mSimpleList.addView(item);//you can add layout params if you want
}
}
I just had to put android:fillViewport="true" to SwipeRefreshLayout. And now RecyclerView is visible.
My earlier answer is blocking the down scroll. So, a good work around will be add your Stuff as the first element of the RecyclerView. That can be easily implemented using the adapter. That way you can still scroll your stuff as well as your actual list elements.
<?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">
<include layout="#layout/toolbar"></include>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/simpleList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#+id/your_stuff" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
And using something like the following for your adapter implimentation,
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class YourStuffViewHolder extends RecyclerView.ViewHolder {
//
}
class ViewHolderListItem extends RecyclerView.ViewHolder {
//
}
#Override
public int getItemViewType(int position) {
if(position>0){
return 1;
}
return 0;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 0: return new YourStuffViewHolder();
case 1: return new ViewHolderListItem ();
}
}
}
I've implemented a swipe refresh layout onto one of my List Views however the view is not sliding down when I swipe and the icon is not visible. Even though it seems it doesn't work, it does actually fire off the OnRefresh listener.
Also I think its worth mentioning that I'm using the ListView on a fragment so i'm initializing the listener in the fragment activity which is displayed below.
Swipe Refresh XML
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"
android:layout_gravity="center_horizontal"
android:dividerHeight="1sp"
android:translationZ="5dp"
android:background="#color/background_gray"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:clickable="true"
/>
</android.support.v4.widget.SwipeRefreshLayout>
Fragment Activity
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) getActivity().findViewById(R.id.swipe_refresh_layout);
ListView lView = (ListView) getActivity().findViewById(R.id.listView);
mSwipeRefreshLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mSwipeRefreshLayout.setRefreshing(true);
((MainActivity) getActivity()).refresh();
new Handler().postDelayed(new Runnable() {
#Override public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
}, 5000);
}
});
lView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
#Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0)
mSwipeRefreshLayout.setEnabled(true);
else
mSwipeRefreshLayout.setEnabled(false);
}
});
}
I solved it, it appears that this is a current bug with the SwipeRefreshLayout. It will only work when Listview is wrapped inside a FrameLayout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"
android:layout_gravity="center_horizontal"
android:dividerHeight="1sp"
android:translationZ="5dp"
android:background="#color/background_gray"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:clickable="true"
/>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
Simply set the property [android:clickable="true"] for the Immediate clild layout of SwipeRefreshLayout which occupies complete screen area.i.e. whose width and height is match_parent.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/srlayout_Container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true">
<RelativeLayout
android:id="#+id/rl_MainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true">
<!-- Placeholder for Other View or ViewGroup as Clild -->
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
I have a fragment inside my main activity. I want to update the contents of the fragment dynamically a run time. Specifically, I want to populate the contents of fragment with new data on button back press. Please help me out in the same and suggest me how to achieve such a functionality.
//main_activity.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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical"
android:id="#+id/container">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar" />
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/fragment_recyclerview"
android:name="com.example.RecyclerViewFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:layout="#layout/fragment_recyclerview" />
</FrameLayout>
<fragment
android:id="#+id/fragment_navigation_drawer"
android:name="com.example.NavigationDrawerFragment"
android:layout_width="#dimen/drawer_dimen"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
The first fragment is the one that needs to be updated
#Override
public void onBackPressed() {
//Find if fragment by tag
Fragment fr = fragmentManager.findFragmentByTag("home");
if (fr.isVisible()) {
//do ur stuff
} else {
fragmentManager.beginTransaction().show(fr).commit();
}
}
Ok! I will give you an example of what I did in one of my projects...
My main activity xml contained a simple linear layout among other things:
<LinearLayout
android:id="#+id/layout_images_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9"
android:orientation="horizontal" >
</LinearLayout>
In my activity OnCreate, I added the following:
FragmentImages fragmentImages = new FragmentImages();
getFragmentManager().beginTransaction().add(R.id.layout_images_fragment, fragmentImages).commit();
where FragmentImages is a class that extends Fragment
public class FragmentImages extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_images, container, false);
//and here is where I wrote my codes for this fragment
return v;
}
}
Hope this will help !!