How to put EditText and Send Button in Fragment's Recyclerview? - android

I have an activity with three Fragments. Is there a way to add Chat functionality on one of Fragments. Details mentioned below. Let me know if anything else is required.
XML file of the activity is listed below.
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
.........
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
......
</android.support.design.widget.CoordinatorLayout>
Fragment's XML for inflating RecyclerView is listed below:-
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/messageList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_below ="#id/appbar"
>
</android.support.v7.widget.RecyclerView>
My two Fragments are working fine. For third Fragment, I have attached adapter for listing chat message which is working fine however I am unable to attach Edittext and send button for chat functionality which I believed shall be outside adapter but inside Fragment. Can somebody please advise how this can be achieved? I have lost couple of hours in figuring out how this can be achieved? Thanks in advance for your help.
XML for third Fragment is below. Is there a way to display EditText, Send Button and Chatlist in the same Fragment? Chatlist is not a problem. The real issue is to set EditText and Send Button.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/newMessageContainer"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/newMessage"
android:focusedByDefault="false"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/send"
android:text="Send"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/messageList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_below ="#id/appbar"
android:layout_above="#id/newMessageContainer"
/>
</RelativeLayout>
EDIT
See Fragment.java file that I have implemented. I am getting error possibly due to ConstraintLayout
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {
RecyclerView rv = (RecyclerView) inflater.inflate(
R.layout.fragment_cheese_list, container, false);
setupRecyclerView(rv);
return rv;
}
private void setupRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new
LinearLayoutManager(recyclerView.getContext()));
recyclerView.setAdapter(new
SimpleStringRecyclerViewAdapter(getActivity(),
getRandomSublist(Cheeses.sCheeseStrings, 30)));
}

Here is your code updated. Just design like this your are passing wrong way there is link below where you can learn to code android app and is pretty mainted by developer.
Set fragment like this and pass layout as I have passed
private RecyclerView recyclerView;
private MyAdapter myAdapter;
#Override
public View onCreate(Bundle savedInstanceState){
myAdapter=new MyAdpter();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_sample, parentViewGroup, false);
recyclerView= rootView.findViewById(R.id.recyelerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(c);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(myAdapter);
return rootView;
}
private void setupRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new
LinearLayoutManager(recyclerView.getContext()));
recyclerView.setAdapter(new
SimpleStringRecyclerViewAdapter(getActivity(),
getRandomSublist(Cheeses.sCheeseStrings, 30)));
}
Please follow this if you are new
https://guides.codepath.com/android/Using-the-RecyclerView

Try this it work for me also got button click. And keep button click code on Fragment not in recyclerview
<?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">
<Button
android:id="#+id/button"
android:layout_width="88dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="#+id/editText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/editText"
app:layout_constraintTop_toTopOf="#+id/editText" />
<EditText
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button"
app:layout_constraintStart_toStartOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

Related

View Pager is empty only at first time

I have a fragment that contains recycle view and on every item press another fragment is shown that holding a view pager that shows fragment on every swipe. when I first enter to the fragment after pressing the recycle view item the pager is not visible.
on second time and the rest of the times the data is shown as expected.
code:
main fragment holds view pager:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/lineItems"
style="#style/TitleTextView"/>
<android.support.v4.view.ViewPager
android:id="#+id/CardTablepager"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"/>
</LinearLayout>
content fragment (view pager swipes this fragment) :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/poMainlayout">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/CardViewStyle"
android:layout_margin="8dp"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/poLineItemsTable"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbarStyle="outsideInset"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
I read few posts with no help: Android Viewpager display wrong data on first load
I also tried to invalidate the adapter from the main fragment with no help:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewPager.getAdapter().notifyDataSetChanged();
}
any ideas?
Just notify your adapter onCreateView not onViewCreated
#Override
public void onCreateView(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewPager.getAdapter().notifyDataSetChanged();
}
Try below changes to your viewpager,
<android.support.v4.view.ViewPager
android:id="#+id/CardTablepager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="600dp"
android:layout_weight="1"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
And for RecyclerView set following properties:
recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);

how to use SwipeRefreshLayout with Fragments

So i was using SwipeRefreshLayout and Fragments for a simple app that i am working on and i have three files:
1.app_bar_main.xml which contains a FrameLayout which is a container for the fragments heres the code:
<?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"
android:fitsSystemWindows="true"
tools:context="com.example.surafel.tryingfragment.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="58dp"
>
</FrameLayout>
<android.support.design.widget.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"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
2.fragment_main.xml which contains components of the main fragment and a SwipeRefreshLayout heres the code:
<android.support.v4.widget.SwipeRefreshLayout 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:id="#+id/refreshMainContent"
tools:context="com.example.surafel.tryingfragment.MainFragment">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MAIN"
android:padding="8dp"
android:textColor="#fff"
android:background="#color/colorPrimary"
android:textSize="28sp"
android:id="#+id/buttonmain"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
3.MainFragment.java this is the java code for the fragment_main.xml heres the code
//i have imported all the necessary classes
public class MainFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
SwipeRefreshLayout swipeView;
public MainFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_main,container,false);
swipeView = (SwipeRefreshLayout) layout.findViewById(R.id.refreshMainContent);
swipeView.setColorSchemeColors(getResources().getColor(android.R.color.holo_blue_dark),getResources().getColor(android.R.color.holo_red_dark),getResources().getColor(android.R.color.holo_green_light),getResources().getColor(android.R.color.holo_orange_dark));
swipeView.setOnRefreshListener(this);
return inflater.inflate(R.layout.fragment_main, container, false);
}
public void onRefresh() {
Log.d("Refreshing","The refresh is working");
}
}
4.i also have MainActivity.java file which contains all the necessary codes
the problem is its not changing the color of the swipeView and its not even calling the onRefresh() method. when i run the
app and swipe down the refresher comes but its color is black and its not executing the onRefresh() method.
and also there are no compiletime and runtime errors.
So can anyone please help me,i posted all the code because i thought it could be usefull,Thanks.
It seems like you have called the code inflater.inflate(R.layout.fragment_main, container, false); twice.
Try returning the object layout instead of inflater.inflate(R.layout.fragment_main, container, false)

ItemDecorator for RecyclerView with CardViews not working

I am trying to use ItemDecorator to achieve spacing between CardViews inside a RecyclerView. For that I am using as reference this answer but the spacing isn't applied. I Also tried with this answer but no avail.
Here is the XML for the RecyclerView:
<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.company.name.MyFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerviewId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
/>
</FrameLayout>
Here is the XML for the CardView:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/cardView"
card_view:cardElevation="2dp"
>
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="100dp"
android:layout_height="98dp"
card_view:srcCompat="#mipmap/ic_launcher"
card_view:layout_constraintTop_toTopOf="parent"
card_view:layout_constraintLeft_toLeftOf="parent"/>
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
The code for the item decorators are the ones presented in the consulted answers.
What could be the reason for the spacing not to be applied?
EDIT 1:
Here's the code to assign the item decorator:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
...
myRecyclerView.setLayoutManager(new GridLayoutManager(activity, 2));
myRecyclerView.addItemDecoration(new SpacingGridView(activity, R.dimen.my_spacing), 0);
...
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState)
MyAdapter adapter = MyAdapter(getData());
myRecyclerView.setAdapter(adapter);
}

Fragment Transaction

I have a ListFragment with a floating action button. When the button is clicked, i want to replace the ListFragment with a CreateListFragment. Instead, the CreateListFragment is placed on top of the ListFragment and the button and textview from the ListFragment are still visible. I am not sure what went wrong. How do I completely replace the ListFragment with the CreateListFragment?
Here is the screenshot before the button is clicked
http://i.stack.imgur.com/k2HxP.png
Here is a screenshot after the button is clicked
http://i.stack.imgur.com/TYN47.png
list_fragment
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listFrame">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fab"
android:layout_gravity="bottom|end"
app:backgroundTint="#color/colorAccent"
android:src="#drawable/create"/>
<TextView
android:id="#+id/tvEmpty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:hint="No Shopping Lists Yet"
android:layout_gravity="center"
android:textSize="20sp"/>
</FrameLayout>``
createlist_fragment
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
tools:context="com.lavineoluoch.helloworld.swiftpay.app.CreateListFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/etListTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/title"/>
<EditText
android:id="#+id/etAddItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/items"/>
<RelativeLayout
android:id="#+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/btnEditItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btnEdit"
android:background="#color/colorPrimary"
android:textColor="#color/white"
/>
</RelativeLayout>
</LinearLayout>
ListFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.list_fragment, container, false);
fab = (FloatingActionButton)view.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CreateListFragment createListFragment = new CreateListFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.listFrame,createListFragment);
fragmentTransaction.commit();
}
});
return view;
}
In your root view for your Fragments insert this line of code:
android:background="?android:windowBackground"
As you have a see through background your view can still see the reminiscence of the replaced Fragment as the view hasn't yet updated.
The above answer should solve your problem, however I would recommend re-structuring your approach and instead launching a new Activity which contains the CreateListFragment when the FAB is pressed. Doing so would result in easier to maintain code which is also easier to read and would be best practice. It would also mean that the user can press their back button and navigate back to ListActivity/ListFragment without you needing to manually handle Fragment back stacks.

FAB position changes when listview's setAdapter method is called

I'm using this library for the fab implementation.
As you can see in this video, the fab position is changing when the fragment loads.
After debugging it, I found that the listview "setAdapter()" method causes the position change.
I don't have a clue why it's happening..
My layout:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/AppTheme.ActionBar" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/toolbar">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/sad_face"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/no_leagues" />
</LinearLayout>
</FrameLayout>
<com.melnykov.fab.FloatingActionButton
android:id="#+id/fab_new_league"
android:src="#drawable/ic_action_add"
app:fab_colorNormal="#color/orange"
app:fab_colorPressed="#color/redDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignBottom="#id/toolbar"
android:layout_marginBottom="-28dp"
android:layout_marginRight="28dp"
android:elevation="8dp"/>
</RelativeLayout>
My fragment
public class LeagueListFragment extends MyFragment {
#InjectView(android.R.id.list) ListView mListView;
#InjectView(android.R.id.empty) LinearLayout mEmpty;
public static Fragment newInstance() {
return new LeagueListFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_league_list, container, false);
ButterKnife.inject(this, view);
// Fetch league list and set up adapter
List<League> list = League.getAll();
mAdapter = new LeagueAdapter(getActivity(), list);
// Set up ListView
mListView.setEmptyView(mEmpty);
mListView.setDivider(new ColorDrawable(getResources().getColor(R.color.gray)));
mListView.setDividerHeight(2);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(this);
return view;
}
}
Margin changes in the runtime on pre-Lollipop because shadow mustn't be taken into account when margins are set.
Try to disable the shadow by :
fab:fab_shadow="false"
Fixing the issue is not expected for now.. (See makovkastar answer)

Categories

Resources