I have an Activity which loads a Fragment using getFragmentManager() . The fragment is working perfecty until an android notification appears. After that, the fragment becomes empty.
This is my application after the activity has loaded the fragment. The red square is the fragment.
Here, a external notification arrives to the mobile:
Only the fragment becomes empty:
Here my Activity:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, FragmentSettings.OnFragmentInteractionListener{
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (fragmentManager == null) {
fragmentManager = getSupportFragmentManager();
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
if (id == R.id.nav_locker_room) {
fragmentNameSection = "FragmentLockerRoom";
fragment = FragmentLockerRoom.newInstance(user, "");
}
fragmentManager.beginTransaction().replace(R.id.flContent, fragment, fragmentNameSection).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
#Override
public void onResume() {
super.onResume();
}
}
Here the activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#drawable/side_nav_menu"
app:itemTextColor="#android:color/white"
app:itemIconTint="#android:color/white"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
And finally this is my Fragment:
public class FragmentSettings extends Fragment {
private static final String ARG_USER = "user";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
getUser user;
View v;
DatabaseManager db;
private OnFragmentInteractionListener mListener;
ToggleButton notificationTrain, notificationNextMatch, liveSounds;
LayoutInflater inflater;
ViewGroup container;
FragmentSettings fragmentSettings;
public FragmentSettings() {
}
public static FragmentSettings newInstance(getUser user, String param2) {
FragmentSettings fragment = new FragmentSettings();
Bundle args = new Bundle();
args.putSerializable(ARG_USER, user);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
user = (com.androidsrc.futbolin.communications.http.auth.get.getUser) getArguments().getSerializable(ARG_USER);
mParam2 = getArguments().getString(ARG_PARAM2);
}
this.fragmentSettings = this;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
this.inflater = inflater;
this.container = container;
buildLayout();
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public void buildLayout(){
db = new DatabaseManager(getActivity());
v = inflater.inflate(R.layout.fragment_fragment_settings, container, false);
notificationTrain = v.findViewById(R.id.fragment_settings_notification_trainment_toggle);
notificationNextMatch = v.findViewById(R.id.fragment_settings_notification_next_match_toggle);
liveSounds = v.findViewById(R.id.fragment_settings_notification_live_sounds_toggle);
notificationTrain.setChecked(db.findNotification().isTrainActive());
notificationNextMatch.setChecked(db.findNotification().isMatchActive());
liveSounds.setChecked(db.findNotification().isLiveSoundsActive());
Log.e("notif",db.findNotification().toString());
notificationTrain.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
if(db == null){
db = new DatabaseManager(getActivity());
}
Notification notification = db.findNotification();
notification.setTrainActive(isChecked);
db.saveNotification(notification);
}
}) ;
notificationNextMatch.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
if(db == null){
db = new DatabaseManager(getActivity());
}
Notification notification = db.findNotification();
notification.setMatchActive(isChecked);
db.saveNotification(notification);
}
}) ;
liveSounds.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
if(db == null){
db = new DatabaseManager(getActivity());
}
Notification notification = db.findNotification();
notification.setLiveSoundsActive(isChecked);
db.saveNotification(notification);
}
}) ;
}
}
And the layout of my Fragment is:
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView
android:id="#+id/fragment_locker_room_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="60dp"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/fragment_locker_room_total_constraint_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!--
REST OF VIEWS
-->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</LinearLayout>
Finally I found the solution. And ScrollView that has a layout_height="match_parent" when a notification is received changes his layout_height to 0.
Changing layout_height="match_parent" to layout_height="wrap_content" in ScrollView solves the issue.
Related
I detected something strange when executing my code.
I deleted a lot of code to try to detect the error.
I use two fragment.
In the first Fragment I read from a database using volley +.
When loading a new fragment, by clicking on the fragment, the onclik event of the previous fragment continues to work on the new fragment.
The code executes correctly in the RecyclerView, reads the data from the remote database and no error is detected.
The code of the second fragment: CommentariosArticulo I have not put it because it is empty, only the default template generated by android Studio
I have also verified that if I delete all the code
inside the fragment: ListadoArticulos.java
referring to volley and referring to the Recyclerview and call the second fragment the problem disappears
Articulo.java
---------------
public class Articulo {
private Integer id;
private String titulo;
private String contenido;
private String fecha;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getTitulo() { return titulo; }
public void setTitulo(String titulo) { this.titulo = titulo; }
public String getContenido() { return contenido; }
public void setContenido(String contenido) { this.contenido = contenido; }
public String getFecha() { return fecha; }
public void setFecha(String fecha) { this.fecha = fecha; }
}
ArticulosAdapter.java
---------------------
package com.example.suso.audioblogsuso_pru003.datos;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.suso.audioblogsuso_pru003.R;
import java.util.List;
public class ArticulosAdapter extends
RecyclerView.Adapter<ArticulosAdapter.ArticulosHolder>
implements View.OnClickListener{
private List<Articulo> listaArticulos;
private View.OnClickListener onClickListener;
public ArticulosAdapter(List<Articulo> listaArticulos) {
this.listaArticulos = listaArticulos;
}
#Override
public ArticulosHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View vista= LayoutInflater.from(parent.getContext()).
inflate(R.layout.articulos_item,parent,false);
RecyclerView.LayoutParams layoutParams=new RecyclerView.
LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
vista.setLayoutParams(layoutParams);
vista.setOnClickListener(this); // para que capte el evento click
return new ArticulosHolder(vista);
}
#Override
public void onBindViewHolder(ArticulosHolder holder, int position) {
holder.txtId.setText(listaArticulos.get(position).getId().toString());
holder.txtTitulo.setText(listaArticulos.get(position).getTitulo().toString());
holder.txtFecha.setText(listaArticulos.get(position).getFecha().toString());
}
#Override
public int getItemCount() {
return listaArticulos.size();
}
public void setOnClickListener(View.OnClickListener onClickListener){
this.onClickListener = onClickListener;
}
#Override
public void onClick(View v) {
if(onClickListener != null){
onClickListener.onClick(v);
}
}
public class ArticulosHolder extends RecyclerView.ViewHolder{
TextView txtId, txtTitulo, txtFecha;
public ArticulosHolder(View itemView) {
super(itemView);
txtId = (TextView) itemView.findViewById(R.id.idArticulo);
txtTitulo = (TextView) itemView.findViewById(R.id.tituloArticulo);
txtFecha =(TextView) itemView.findViewById(R.id.fechaArticulo);
}
}
}
mainActivity.java
-----------------
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener ,
ComentariosArticulo.OnFragmentInteractionListener,
ListadoArticulos.OnFragmentInteractionListener
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment miFragment = null;
boolean fragmentSeleccionado = false;
if (id == R.id.listadoArticulos) {
miFragment = new ListadoArticulos();
fragmentSeleccionado=true;
}
if(fragmentSeleccionado){
getSupportFragmentManager().beginTransaction().replace(R.id.content_main,miFragment).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
Listado Articulos.java
----------------------
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link ListadoArticulos.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link ListadoArticulos#newInstance} factory method to
* create an instance of this fragment.
*/
public class ListadoArticulos extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
MiAplicacion miAplicacion;
RecyclerView recyclerArticulos;
ArrayList<Articulo> listaArticulos;
RequestQueue request;
JsonObjectRequest jsonObjectRequest;
TextView tvLoadingListadoArticulos;
public ListadoArticulos() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment ListadoArticulos.
*/
// TODO: Rename and change types and number of parameters
public static ListadoArticulos newInstance(String param1, String param2) {
ListadoArticulos fragment = new ListadoArticulos();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_listado_articulos, container, false);
miAplicacion = (MiAplicacion) getContext().getApplicationContext();
tvLoadingListadoArticulos = (TextView) view.findViewById(R.id.tvLoadingListadoArticulos);
listaArticulos=new ArrayList<>();
recyclerArticulos= (RecyclerView) view.findViewById(R.id.IdReciclerViewListadoArticulos);
//El LayoutManager se encarga del layout de todas las vistas dentro del RecyclerView
recyclerArticulos.setLayoutManager(new LinearLayoutManager(this.getContext()));
//el tamaño del recyclerView no depende del adaptador
recyclerArticulos.setHasFixedSize(true);
request = Volley.newRequestQueue(getContext());
request.getCache().clear();
cargarWebServiceWeb();
return view;
}
private void cargarWebServiceWeb() {
String scriptPhp ="listado-articulos.php";
String url= miAplicacion.getUrlHostScriptPhp()+scriptPhp;
jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,
url,
null,
createMyReqSuccessListenerArticulos(),
createMyReqErrorListenerArticulos());
request.add(jsonObjectRequest);
}
private Response.Listener<JSONObject> createMyReqSuccessListenerArticulos() {
return new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if(response.isNull("articulos")){
Toast.makeText(getContext(), "No se encontró ningun articulo " , Toast.LENGTH_LONG).show();
tvLoadingListadoArticulos.setHeight(0);
return;
}
Articulo articulo=null;
JSONArray json=response.optJSONArray("articulos");
try {
for (int i=0;i<json.length();i++){
articulo=new Articulo();
JSONObject jsonObject=null;
jsonObject=json.getJSONObject(i);
articulo.setId((Integer)jsonObject.optInt("ID"));
articulo.setTitulo(jsonObject.optString("post_title"));
articulo.setContenido(jsonObject.optString("post_content"));
articulo.setFecha("fecha");
listaArticulos.add(articulo);
}
ArticulosAdapter adapter=new ArticulosAdapter(listaArticulos);
adapter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(),"estoy creando un nuevo fragment", Toast.LENGTH_LONG).show();
// Crea el nuevo fragmento y la transacción.
Fragment miFragment = new ComentariosArticulo();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
//el id:R.id.BuscarArticulosCategoria pertenece al
//contenedor del fragment_buscar_articulos_categoria.xml (fragment actual)
transaction.replace(R.id.contenListadoArticulos, miFragment);
transaction.addToBackStack(null);
// Commit a la transacción
transaction.commit();
}
});
tvLoadingListadoArticulos.setHeight(0);
recyclerArticulos.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getContext(), "No se ha podido establecer conexión con el servidor" +
" "+response, Toast.LENGTH_LONG).show();
}
}
};
}
private Response.ErrorListener createMyReqErrorListenerArticulos() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), "No se ha podido conectar con el servidor" + error, Toast.LENGTH_LONG).show();
Log.i("ERROR", error.toString());
}
};
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Articulos_item.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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/idArticulo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="18"
android:text="id"
android:textSize="16sp"
android:visibility="invisible" />
<TextView
android:id="#+id/tituloArticulo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="6"
android:text="titulo"
android:textSize="16sp" />
<TextView
android:id="#+id/fechaArticulo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="13"
android:text="fecha"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="#979B9C"/>
</LinearLayout>
fragment_listado_articulos.xml
------------------------------
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contenListadoArticulos"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFE2E7EA"
tools:context=".gestion_datos.ListadoArticulos">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="#drawable/border_style2"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="Listado Artículos"
android:textAlignment="center"
android:textSize="16dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/IdReciclerViewListadoArticulos"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:textAlignment="center">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</ScrollView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tvLoadingListadoArticulos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorNaranjaCrema2"
android:gravity="center"
android:text="cargando ...."
android:textSize="20dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal"
android:padding="2dp"
android:text="Selecciona un Un Artículo"
android:textSize="16dp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
fragment_comentarios_articulo.xml
----------------------------------
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contenComentariosArticulo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/coloNaranjaCremar"
tools:context=".gestion_datos.ComentariosArticulo">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>
This is happening because you are adding the CommentariosArticulo Fragment as a child to the ListadoArticulos Fragment, and both the CommentariosArticulo fragment and the recyclerview reside in the same FrameLayout contenListadoArticulos.
You need to replace the fragment in the MainActivity class not in ListadoArticulos.
Just move the following code from your ListadoArticulos to MainActivity
Fragment miFragment = new ComentariosArticulo();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
//el id:R.id.BuscarArticulosCategoria pertenece al
//contenedor del fragment_buscar_articulos_categoria.xml (fragment actual)
transaction.replace(R.id.contenListadoArticulos, miFragment);
transaction.addToBackStack(null);
// Commit a la transacción
transaction.commit();
I have implemented the SwipeRefreshLayout in many of the pages,and it working fine. but here i got stuck with one specific implementation , where i have a SwipeRefreshLayout for the ViewPager and ViewPager holding the FragmentPagerAdapter.
In my case , I have a ViewPager with two tabs and each holding the fragment with RecyclerView. On main page I have a SwipeRefreshLayout and on the onRefresh i need to load the API and update the fragments in ViewPager. Updating is working fine but unfortunately RecyclerView inside the Fragment ( ViewPager tab Item ) not scrolling top and it always calling the SwipeToRefresh.
I am familiar with using the SwipeRefreshLayout with RecyclerView, but here the problem is the main child of the SwipeRefreshLayout is ViewPager and it having the Fragment inside it and that fragment is holding the RecyclerView.
I have a thought of moving the SwipeRefreshLayout inside the fragments for the RecyclerView , but again here i have challenges like both the Fragments is having the same API. So that i am using the SwipeRefreshLayout directly on ViewPager to refresh my data.
Here is some of my codes.
MainContacts.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/ll_no_records"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="#+id/iv_retry"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:contentDescription="#string/todo"
android:src="#drawable/ic_reload" />
<TextView
android:id="#+id/textError"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:gravity="center"
android:text="#string/no_contact_found"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#color/colorDarkGray" />
</LinearLayout>
<LinearLayout
android:id="#+id/ll_process"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:alpha="1"
android:gravity="center"
android:orientation="vertical"
android:visibility="visible">
<ProgressBar
android:id="#+id/progress"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:indeterminate="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/fetching"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#color/colorDarkGray" />
</LinearLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/contacts_screen"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.support.design.widget.TabLayout
android:id="#+id/my_contacts_tabs"
style="#style/MyCustomTabLayout"
android:layout_width="match_parent"
app:tabBackground="#color/colorWhite"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/my_contacts_view_pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/transparent" >
</android.support.v4.view.ViewPager>
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
contacts.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:hc="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/ll_no_records"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="#+id/iv_retry"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:contentDescription="#string/todo"
android:src="#drawable/ic_reload" />
<TextView
android:id="#+id/textError"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:gravity="center"
android:text="#string/no_contact_found"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#color/colorDarkGray" />
</LinearLayout>
<com.diegocarloslima.fgelv.lib.FloatingGroupExpandableListView
android:id="#+id/contactList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/searchContainer"
android:animateLayoutChanges="true"
android:childDivider="#android:color/transparent" />
</RelativeLayout>
MainFragment ( Which i am using to load the child fragments , SwipeTORefreshLayout + ViewPager here)
public class MainFragment extends BaseFragment {
private TextView mTextError;
private LinearLayout llNoRecords, ll_process;
private ImageView iv_retry;
private MaterialSearchView materialSearchView;
PHCJsonResponseContactDetailModel mContactResponseModel;
int expandableListSelectionType = ExpandableListView.PACKED_POSITION_TYPE_NULL;
boolean actionModeEnabled;
private Activity mActivity;
SwipeRefreshLayout mSwipeRefreshLayout;
private ViewPager viewPager;
TabLayout tabLayout;
ContactsTabPagerAdapter mAdapter;
ArrayList<PHCContactDetailModel> mContactList =new ArrayList<>();
ArrayList<PHCContactDetailModel> mFavoriteList;
boolean isSwipeToRefresh;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mActivity = getActivity();
View view = inflater.inflate(R.layout.phc_contact_fragment, container, false);
getViewId(view);
setListener();
if (isNetworkAvailable()) {
if(((MainDrawerActivity)mActivity).getPHCContactFragmentData()==null)
getAllContactData();
else
updateWidgets();
} else {
showNoNetworkToast();
llNoRecords.setVisibility(View.VISIBLE);
mTextError.setText(getResources().getText(R.string.no_internet_retry));
}
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onResume() {
super.onResume();
}
/*#Override
public void onPrepareOptionsMenu(final Menu menu) {
getActivity().getMenuInflater().inflate(R.menu.menu_fragment_group, menu);
}*/
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_fragment_contacts, menu);
MenuItem item = menu.findItem(R.id.action_search);
materialSearchView.setMenuItem(item);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_create_group) {
Intent createGroupIntent = new Intent(getActivity(), PHCCreateGroupActivity.class);
createGroupIntent.putExtra("comeFrom", PHCAppConstant.GROUP_ADD);
getActivity().startActivity(createGroupIntent);
}
return super.onOptionsItemSelected(item);
}
private void setListener() {
iv_retry.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isNetworkAvailable()) {
getAllContactData();
} else {
showNoNetworkToast();
}
}
});
}
private void getViewId(View view) {
mTextError = (TextView) view.findViewById(R.id.textError);
ll_process = (LinearLayout) view.findViewById(R.id.ll_process);
llNoRecords = (LinearLayout) view.findViewById(R.id.ll_no_records);
iv_retry = (ImageView) view.findViewById(R.id.iv_retry);
viewPager = (ViewPager) view.findViewById(R.id.my_contacts_view_pager);
tabLayout = (TabLayout) view.findViewById(R.id.my_contacts_tabs);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout);
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary,
android.R.color.holo_green_dark,
android.R.color.holo_orange_dark,
android.R.color.holo_blue_dark);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
if(mContactResponseModel!=null && mContactResponseModel.getData().size() >0)
{
isSwipeToRefresh = true;
getAllContactData();
}
}
});
materialSearchView = (MaterialSearchView) getActivity().findViewById(R.id.search_view);
}
private void getAllContactData() {
if (isNetworkAvailable()) {
// showProgress();
PHCApiInterface apiService = PHCApiClient.getClient(getActivity()).create(PHCApiInterface.class);
Call<PHCJsonResponseContactDetailModel> call = apiService.contactData(getApplicationData(getActivity()).getAuthToken(), getApplicationData(getActivity()).getUserID());
call.enqueue(new Callback<PHCJsonResponseContactDetailModel>() {
#Override
public void onResponse(Call<PHCJsonResponseContactDetailModel> call, Response<PHCJsonResponseContactDetailModel> response) {
Log.d(TAG, "getContacts URL " + response.raw().request().url());
Log.d(TAG, "getContacts Resp " + new Gson().toJson(response.body()));
mContactResponseModel = response.body();
((MainDrawerActivity)mActivity).setPHCContactFragmentData(mContactResponseModel);
if(mSwipeRefreshLayout.isRefreshing())
{
// cancel the Visual indication of a refresh
mSwipeRefreshLayout.setRefreshing(false);
}
if(isSwipeToRefresh)
{
isSwipeToRefresh=false;
updateWidgets();
}
else
updateWidgets();
}
#Override
public void onFailure(Call<PHCJsonResponseContactDetailModel> call, Throwable t) {
if(mSwipeRefreshLayout.isRefreshing())
{
// cancel the Visual indication of a refresh
mSwipeRefreshLayout.setRefreshing(false);
}
isSwipeToRefresh=false;
dismissProgress();
mTextError.setVisibility(View.VISIBLE);
}
});
} else {
isSwipeToRefresh=false;
if(mSwipeRefreshLayout.isRefreshing())
{
// cancel the Visual indication of a refresh
mSwipeRefreshLayout.setRefreshing(false);
}
showNoNetworkAlert();
}
}
private void updateWidgets() {
if (mContactResponseModel.getStatusCode() == 401 || mContactResponseModel.getStatusCode() == 402) {
showSessionExpireAlert(mContactResponseModel.getStatusMessage(), mContactResponseModel.getStatusCode());
return;
}
if (mContactResponseModel != null && mContactResponseModel.getStatusCode() == 1) {
dismissProgress();
mTextError.setVisibility(View.GONE);
mContactList = mContactResponseModel.getData();
mFavoriteList = mContactResponseModel.getData();
if(mContactList!=null && mContactList.size()>0)
{
llNoRecords.setVisibility(View.GONE);
mAdapter = new ContactsTabPagerAdapter(getActivity().getApplicationContext(), getChildFragmentManager(), mContactList , mFavoriteList);
viewPager.setAdapter(mAdapter);
tabLayout.setupWithViewPager(viewPager);
}
else {
llNoRecords.setVisibility(View.VISIBLE);
}
} else {
dismissProgress();
mTextError.setVisibility(View.VISIBLE);
}
}
public void dismissProgress() {
ll_process.setVisibility(View.GONE);
super.dismissProgress();
}
private void initiateContactChat(final PHCFacilityDetailsModel facilityDetailsModel, final int groupPosition, final int childPosition) {
String header = getApplicationData(getActivity()).getAuthToken();
PHCApiInterface apiService = PHCApiClient.getClient(getActivity()).create(PHCApiInterface.class);
Call<PHCContactInitiateChatResponseModel> call = apiService.initiateContactChat(header, facilityDetailsModel.getUserId(), getApplicationData(getActivity()).getUserID(), 0);
call.enqueue(new Callback<PHCContactInitiateChatResponseModel>() {
#Override
public void onResponse(Call<PHCContactInitiateChatResponseModel> call, Response<PHCContactInitiateChatResponseModel> response) {
Log.d(TAG, "initiateContactChat URL " + response.raw().request().url());
Log.d(TAG, "initiateContactChat Resp " + new Gson().toJson(response.body()));
PHCContactInitiateChatResponseModel mContactInitiateChatModel = response.body();
if (mContactInitiateChatModel != null && mContactInitiateChatModel.getStatusCode() == 1) {
Intent chatIntent = new Intent(getActivity(), PHCChatActivity.class);
// chatIntent.putExtra("headerName",mData.get(groupPosition).getFacilityDetails().get(childPosition).getUserName());
chatIntent.putExtra("headerName", facilityDetailsModel.getUserName());
chatIntent.putExtra("groupId", mContactInitiateChatModel.getData().getGroupId());
getActivity().startActivity(chatIntent);
}
}
#Override
public void onFailure(Call<PHCContactInitiateChatResponseModel> call, Throwable t) {
Toast.makeText(getActivity(), "Something went wrong! Please try again", Toast.LENGTH_SHORT).show();
}
});
}
}
ContactsTabPagerAdapter.java
public class ContactsTabPagerAdapter extends FragmentPagerAdapter {
/**
* The Page count.
*/
final int PAGE_COUNT = 2;
private String[] tabTitles = { "Contacts", "Favorites" };
private ArrayList<PHCContactDetailModel> mContactsList;
private ArrayList<PHCContactDetailModel> mFavoritesList;
Context mContext ;
public ContactsTabPagerAdapter(Context context, FragmentManager fm ,ArrayList<PHCContactDetailModel> contacts , ArrayList<PHCContactDetailModel> favs) {
super(fm);
this.mContext = context;
this.mContactsList = contacts;
this.mFavoritesList=favs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
ContactsFragment mContactsFragment =new ContactsFragment();
Bundle bundle=new Bundle();
bundle.putSerializable("Contacts", (Serializable) mContactsList);
mContactsFragment.setArguments(bundle);
return mContactsFragment;
case 1:
FavoritesFragment mFavoritesFragment=new FavoritesFragment();
Bundle pastBundle=new Bundle();
pastBundle.putSerializable("Favorites", (Serializable) mFavoritesList);
mFavoritesFragment.setArguments(pastBundle);
return mFavoritesFragment;
}
return null;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
/**
* Update.
*
* #param lContactsList contact list to update
* #param lFavoritesList favorites list to update
*/
//call this method to update fragments in ViewPager dynamically
public void update(ArrayList<PHCContactDetailModel> lContactsList, ArrayList<PHCContactDetailModel> lFavoritesList) {
this.mContactsList = lContactsList;
this.mFavoritesList = lFavoritesList;
notifyDataSetChanged();
}
#Override
public int getItemPosition(Object object) {
if (object instanceof UpdatableFragment) {
((UpdatableFragment) object).update(mContactsList, mFavoritesList);
}
//don't return POSITION_NONE, avoid fragment recreation.
return super.getItemPosition(object);
}
}
ContactsFragment.java
public class ContactsFragment extends BaseFragment implements UpdatableFragment{
private static final String TAG = "ContactFragmentTab";
private FloatingGroupExpandableListView mContactExpandableList;
private PHCContactAdapter mAdapter;
WrapperExpandableListAdapter wrapperAdapter;
boolean actionModeEnabled;
private LinearLayout llNoRecords;
private ArrayList<PHCContactDetailModel> mContactsData;
public ContactsFragment() {
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
}
#SuppressWarnings("unchecked")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_contacts, container, false);
getViewId(rootView);
Bundle bundle= getArguments();
if(bundle !=null)
{
Log.d(TAG, "bundle is not empty");
mContactsData= (ArrayList<PHCContactDetailModel>) bundle.getSerializable("Contacts");
}
System.out.print("Contacts Size::" + mContactsData.size());
if(mContactsData!=null)
{
updateWidgets();
}
return rootView;
}
private void updateWidgets() {
mAdapter = new PHCContactAdapter(getActivity(), mContactsData, new ListShowingHidingListener() {
#Override
public void listHideAndShow(boolean isData) {
if (isData) {
llNoRecords.setVisibility(View.GONE);
mContactExpandableList.setVisibility(View.VISIBLE);
listUpdate();
} else {
llNoRecords.setVisibility(View.VISIBLE);
mContactExpandableList.setVisibility(View.GONE);
}
}
});
wrapperAdapter = new WrapperExpandableListAdapter(mAdapter);
mContactExpandableList.setAdapter(wrapperAdapter);
try {
for (int i = 0; i < wrapperAdapter.getGroupCount(); i++) {
mContactExpandableList.expandGroup(i);
}
} catch (Exception e) {
Log.e("Exception in Expand", "" + e);
}
}
private void listUpdate() {
try {
for (int i = 0; i < wrapperAdapter.getGroupCount(); i++) {
mContactExpandableList.expandGroup(i);
}
} catch (Exception e) {
Log.e("Exception in Expand", "" + e);
}
}
private void getViewId(View view) {
// mContactExpandableList = (ExpandableListView) view.findViewById(R.id.contactList);
mContactExpandableList = (FloatingGroupExpandableListView) view.findViewById(R.id.contactList);
}
#Override
public void update(ArrayList<PHCContactDetailModel> contactsData, ArrayList<PHCContactDetailModel> favoritesData) {
this.mContactsData = contactsData;
updateWidgets();
}
}
similarly i have Favorites example as well. Mostly both will look like same, that's why not posting it here.
Sorry for posting the long question. Any help regarding this. Apologies for my poor English. Thanks in Advance.
I want to set the visibility of my relativelayout from my fragment using my adapter see the image below
HERE IS MY FRAGMENT
I declare relativeLayout to public so i can access it on my adapter to set its visibility but i always get an null error
How i can set the relativelayout visibility to visible when i click my checkbox. Please help me. Thanks a lot.
public class FoodListFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public RelativeLayout relativeLayout;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private Food_RecyclerAdapter adapter;
private List<Food> foods;
private ApiInterface apiInterface;
ProgressBar progressBar;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public FoodListFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment FoodListFragment.
*/
// TODO: Rename and change types and number of parameters
public static FoodListFragment newInstance(String param1, String param2) {
FoodListFragment fragment = new FoodListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_food_list, container, false);
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
recyclerView = (RecyclerView)view.findViewById(R.id.recycleViewFood);
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
relativeLayout = (RelativeLayout)view.findViewById(R.id.cart_add);
relativeLayout.setVisibility(View.GONE);
apiInterface = ApiClient.getClient().create(ApiInterface.class);
progressBar = (ProgressBar)view.findViewById(R.id.progress_bar);
progressBar.setVisibility(View.VISIBLE);
Bundle bundle = this.getArguments();
String category_id = bundle.getString("menu_id");
Call<List<Food>> call = apiInterface.getFoodList(category_id);
call.enqueue(new Callback<List<Food>>() {
#Override
public void onResponse(Call<List<Food>> call, Response<List<Food>> response) {
foods = response.body();
adapter = new Food_RecyclerAdapter(getContext(),foods);
recyclerView.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
}
#Override
public void onFailure(Call<List<Food>> call, Throwable t) {
progressBar.setVisibility(View.GONE);
Toast.makeText(getContext(), "Please check your network connection", Toast.LENGTH_SHORT).show();
}
});
EditText searhText = (EditText)view.findViewById(R.id.search_food);
searhText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getfilter().filter(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
HERE IS MY ADAPTER
public class Food_RecyclerAdapter extends RecyclerView.Adapter<Food_RecyclerAdapter.myViewHolder>{
Context context;
public List<Food> foods;
public List<Food> mOriginalValues;
public List<Food> mDisplayedValues;
ApiClient apiClient;
FoodListFragment foodListFragment;
public Food_RecyclerAdapter(Context context,List<Food> foods){
this.context = context;
this.foods = foods;
this.mOriginalValues = foods;
this.mDisplayedValues = foods;
}
#Override
public myViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_list_row,parent,false);
return new myViewHolder(view);
}
#Override
public void onBindViewHolder(final myViewHolder holder, int position) {
apiClient = new ApiClient();
Picasso.with(context).load(apiClient.BASE_URL + foods.get(position).getImage()).into(holder.food_image);
holder.food_check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.food_check.isChecked()){
//HERE I WANT TO SHOW THE RELATIVE LAYOUT WHEN I CLICK MY CHECKBOX
foodlistFragment = new FoodListFragment();
foodListFragment.relativeLayout.setVisibility(View.VISIBLE);
}else{
holder.food_qty.setText(""+0);
}
}
});
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getItemCount() {
return foods.size();
}
public class myViewHolder extends RecyclerView.ViewHolder{
TextView food_price,food_availability,food_qty;
ImageView food_image,remove_image,add_image;
CheckBox food_check;
public myViewHolder(View itemView) {
super(itemView);
food_check = (CheckBox) itemView.findViewById(R.id.radioFood_name);
food_image = (ImageView)itemView.findViewById(R.id.food_image);
food_availability = (TextView) itemView.findViewById(R.id.food_availability);
food_price = (TextView) itemView.findViewById(R.id.food_price);
food_qty = (TextView) itemView.findViewById(R.id.food_qty);
add_image = (ImageView)itemView.findViewById(R.id.add_image);
remove_image = (ImageView)itemView.findViewById(R.id.remove_image);
}
}
}
Here is the XML
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.jampol.blogs.FoodListFragment">
<EditText
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="#+id/search_food"
android:drawableStart="#drawable/ic_search"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:drawablePadding="10dp"
android:hint="Search.."
android:gravity="center_vertical"
android:textSize="18dp"
android:background="#color/colorPrimary"
android:textColorHint="#color/white"
android:textColor="#color/white"
/>
<ProgressBar
android:id="#+id/progress_bar"
style="?android:progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_centerInParent="true"
/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycleViewFood"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:layout_below="#+id/search_food"
android:layout_alignParentStart="true"
android:layout_above="#+id/cart_add">
</android.support.v7.widget.RecyclerView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cart_add"
android:layout_alignParentBottom="true"
android:padding="5dp"
android:layout_alignParentStart="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total"
android:textSize="16dp"
android:paddingRight="10dp"
android:layout_centerVertical="true"
android:textStyle="bold"
android:id="#+id/total"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/total"
android:text="100000"
android:textSize="16dp"
android:layout_centerVertical="true"
android:textStyle="bold"
/>
<Button
android:layout_width="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:background="#color/red"
android:textColor="#color/white"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:text="Add to cart" />
</RelativeLayout>
Hope this will help you.
You do not need to pass fragment's object in your adapter nor you need to define Relativelayout in your fragment as a public.
Follow this steps it may be lengthy but you can achieve your desire result :
Just pass your activity of fragment as a context in your adapter.
Like this :
adapter = new Food_RecyclerAdapter(getActivity(),foods);
Then in your adapter where you want to show or hide your views do something
like this:
Cast your context to your fragment's activity. Let's your fragment is inside
your MainActivity. So this would be :
MainActivity mActivity = ((MainActivity)context);
Make a public method in your MainActivity and getCurrentFragment of your
activity something like this:
public void showHideViews(){
Fragment currentFragment = getActiveFragment();
if(currentFragment != null){
//Access public method of your fragment from here
((FoodListFragment)currentFragment).showHideViews();
}
}
Make showHideViews() method in your FoodListFragment :
public void showHideViews(){
yourRelativeLayout.setVisibility(View.GONE);
}
First time it looks lengthy but this will be convenient.
Hope it helps you.
you need to pass a listener to your fragment like this:
in your adapter:
private MyClickListener clickListener;
interface MyClickListener{
void onClick(View v, int position);
}
public void setOnMyClickListener(MyClickListener clickListener){
this.clickListener = clickListener;
}
in your holder.food_check onClick:
if(clickListener != null){
clickListener.onClick(v,position);
}
in your fragment(when create adapter):
adapter.setOnMyClickListener(new Food_RecyclerAdapter.MyClickListener()
{
#Override
public void onClick(View v,int position) {
relativeLayout.setVisibility(View.VISIBLE);//or gone
}
});
Your foodListFragment object is not initialized in adapter class. it is null and you are trying to call foodListFragment.relativeLayout.setVisibility(View.VISIBLE); on checkbox click listener in adapter.
So pass foodListFragment reference from Fragment to Adapter class and in adapter class constructor make sure it is initialized.
I have an activity that hosts a fragment. The activity essentially has no content except a spinner that indicates the fragment is loading. The fragment is dependent upon a stable internet connection, therefore the length of time required for the spinner to be visible is dynamic in nature.
I want to remove the spinner on the activity after the fragment successfully loads. I tried using the isAdded() method, however that approach did not work. Any help is appreciated:
Fragment:
public class LatestFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private RecyclerView mRecyclerViewForLatestPolls;
private RecyclerView.Adapter mLatestAdapter;
private ArrayList<LatestPoll> mLatestPollsArray;
private DateFormat mDateFormat;
private Date mDate;
private String mCurrentDateString;
private Firebase mBaseRef;
private Firebase mPollRef;
private Firebase mUpdateRef;
private FragmentListener mFragmentListener;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public LatestFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment LatestFragment.
*/
// TODO: Rename and change types and number of parameters
public static LatestFragment newInstance(String param1, String param2) {
LatestFragment fragment = new LatestFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDateFormat = new SimpleDateFormat("MM-dd-yyyy");
mDate = new Date();
mCurrentDateString = mDateFormat.format(mDate);
mBaseRef = FirebaseUtil.FIREBASE;
mPollRef = mBaseRef.child("Polls");
mUpdateRef = mPollRef.child(mCurrentDateString);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_latest, container, false);
getActivity().setTitle(R.string.latest_title);
mRecyclerViewForLatestPolls = (RecyclerView) rootView.findViewById(R.id.latest_RecyclerView);
mLatestPollsArray = new ArrayList<>();
mLatestAdapter = new MyAdapter(mLatestPollsArray);
LinearLayoutManager llm = new LinearLayoutManager(getActivity().getApplicationContext());
llm.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerViewForLatestPolls.setLayoutManager(llm);
mRecyclerViewForLatestPolls.setItemAnimator(new SlideInLeftAnimator());
mRecyclerViewForLatestPolls.setAdapter(new AlphaInAnimationAdapter(mLatestAdapter));
mUpdateRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int numberOfPollsForDay = (int) dataSnapshot.getChildrenCount();
for (int i = 0; i < numberOfPollsForDay; i++) {
String latestPollQuestion = (String) dataSnapshot.child(String.valueOf(i + 1)).child("Poll_Question").getValue();
String pollImageURL = (String) dataSnapshot.child(String.valueOf(i + 1)).child("Image").getValue();
mLatestPollsArray.add(0, new LatestPoll(latestPollQuestion, pollImageURL));
mLatestAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
// Inflate the layout for this fragment
return rootView;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
// Force the parent activity to implement listener.
if (context instanceof FragmentListener) {
mFragmentListener = (FragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
mFragmentListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<LatestPoll> mDataSet;
int lastPosition = -1;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
protected TextView pollQuestion;
protected ImageView pollImage;
public ViewHolder(View v) {
super(v);
pollQuestion = (TextView) v.findViewById(R.id.latest_item_question);
pollImage = (ImageView) v.findViewById(R.id.pollThumbNailImage);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<LatestPoll> myDataset) {
mDataSet = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.latest_item, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
//The OutOfBoundsException is pointing here
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Log.v("ON_BIND", "ON_BINDVIEWHOLDER CALLED");
LatestPoll latestPoll = mDataSet.get(position);
holder.pollQuestion.setText(latestPoll.getQuestion());
Picasso.with(getActivity())
.load(latestPoll.getPollImage())
.fit()
.placeholder(R.drawable.loading_spinnter_white)
.into(holder.pollImage);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataSet.size();
}
}
private void onLoad() {
if (mFragmentListener != null) {
mFragmentListener.onFragmentLoaded();
}
}
public interface FragmentListener {
void onFragmentLoaded();
}
}
Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/action_tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
android:titleTextColor="#color/white">
</android.support.v7.widget.Toolbar>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="#+id/pbHeaderProgress"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:progressDrawable="#drawable/loading_spinnter_white">
</ProgressBar>
<TextView
android:id="#+id/progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/pbHeaderProgress"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="#string/loading_poll_data"
android:textColor="#color/white"
android:textSize="24sp" />
</RelativeLayout>
<FrameLayout
android:id="#+id/latest_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</FrameLayout>
</LinearLayout>
<!-- The navigation drawer -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
Image:
In fragment create a listener interface,
private MyFragmentListener mListener;
/**
* onLoad should be called when the fragment has loaded.
*/
private void onLoad() {
if (mListener != null) {
mListener.onFragmentLoaded();
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
// Force the parent activity to implement listener.
if (context instanceof MyFragmentListener) {
mListener = (MyFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface MyFragmentListener {
void onFragmentLoaded();
}
Then in parent activity,
public class MainActivity extends Activity implements MyFragment.MyFragmentListener{
#Override
public void onFragmentLoad() {
// HIDE the progressbar spinner.
}
See Communicating with Other Fragments for more info.
I'm having navigation drawer with four menu's and each menu has own fragments
, Inside first fragment has view pager sliding tab with 2 fragments,
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<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/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#color/white"
app:tabIndicatorHeight="4dp" />
</android.support.design.widget.AppBarLayout>
////////////// Here I'm replacing each fragments ////////////////
<FrameLayout
android:id="#+id/main_content_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_done"
android:visibility="gone"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header"
app:menu="#menu/drawer_view"/>
</android.support.v4.widget.DrawerLayout>
ManinActivity- DrawerSelection
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass = null;
switch (menuItem.getItemId()) {
case R.id.nav_home:
fragmentClass = Home_Tab_Fragment.class;
break;
case R.id.nav_myorders:
fragmentClass = SecondFragment.class;
break;
case R.id.nav_myoffers:
fragmentClass = ThirdFragment.class;
break;
case R.id.nav_notification:
fragmentClass = FourthFragment.class;
break;
}
fragment = (Fragment) fragmentClass.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.main_content_framelayout, fragment).commit();
mDrawerLayout.closeDrawers();
}
HomeTabFragment
public class Home_Tab_Fragment extends Fragment {
private FragmentActivity myContext;
ViewPager viewPager;
TabLayout tabLayout;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout_viewpager, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.view_pager);
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SlidingTabAdapter adapter = new SlidingTabAdapter(getChildFragmentManager());
adapter.addFragment(new FirstTabFragment(), "First TAB");
adapter.addFragment(new SecondTabFragment(), "Second Tab");
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) getActivity().findViewById(R.id.tabs);
tabLayout.setVisibility(View.VISIBLE);
tabLayout.setupWithViewPager(viewPager);
}
}
SlidingTabAdapter
public class SlidingTabAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public SlidingTabAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
layout_viewpager.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
FirstFragment
public class FirstTabFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
getActivity().setTitle("Foodies");
return rootView ;
}
public void updateFirstFragmentValues(){
//Doing some operations
}
}
Inside MainActivity , I want to call FirstTabFragment method [updateFirstFragmentValues()]
I tried adding TAG in FirstTabFragment ,
public static final String TAG ="FirstTabFragment.TAG";
Then I invoked in MainActivity like below , but Fragment always null.
public void invokeMethodFromFirstTabFragment() {
FragmentManager fm = this.getSupportFragmentManager();
FirstTabFragment fb=(FirstTabFragment)fm.findFragmentByTag(FirstTabFragment.TAG);
if (null != fb) {
fb.updateFirstFragmentValues();
}else{
L.m("Fragment is null===========");
}
}
Kindly advise , How to call "FirstTabFragment" method from inside "MainActivity"
Please note FirstTabFragment is not added directly to MainActivity ,
its added through "Home_Tab_Fragment".
Alright, reading all of the responses of yours, I get that you just simply need to pass data to a fragment upon creation and be able to execute some of Fragment's methods. Ok, simple enough:
IMessageFragment interface
public interface IMessageFragment {
/**
* Method to receive new message text
* #param text Message text to receive
*/
void updateMessageText(String text);
}
MessageFragment
public class MessageFragment extends Fragment implements IMessageFragment {
/**
* Bind views using ButterKnife
*/
#BindView(R.id.textView) TextView mTextView;
/**
* Bundle data
*/
private String mMessageText;
/**
* Unique id of bundle data
*/
private static final String MESSAGE_EXTRA_KEY = "f_message";
/**
* New fragment pattern. This is pretty much all the magic PLUS this
* looks by far better than `new Fragment()` upon instatiation
*/
public static MessageFragment newFragment(String message) {
// 1. Create new fragment
MessageFragment auctionFragment = new MessageFragment();
// 2. Create bundle for fragment params
Bundle args = new Bundle();
// 3. Put position
args.putString(MESSAGE_EXTRA_KEY, message);
// 4. Set arguments
auctionFragment.setArguments(args);
return auctionFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tutorial_fragment, container, false);
/**
* Bind views
*/
ButterKnife.bind(this, view);
// Update UI
updateUI();
return view;
}
/**
* Method to update value of mTextView
*/
private void updateUI() {
if(!mMessageText.equals("")) {
mTextView.setText(mMessageText);
}
}
#Override
public void updateMessageText(String text) {
mMessageText = text;
updateUI();
}
}
Stuff is pretty simple and the interface exists only for good code style and to support design patterns.
Edit:
You cannot directly access FirstTabFragment method from your MainActivity. Firstly you have to call Home_Tab_Fragment method from activity. Then from that method you can call FirstTabFragment method.
Here is strategy:
Step 1: Home_Tab_Fragment to FirstTabFragment communication
define an interface like this
public interface IHomeToFirstFragmentController{
void firstFragmentMethod();
}
Now implements the IHomeToFirstFragmentController in your FirstTabFragment. then you have to implements the firstFragmentMethod().
#overrride
void firstFragmentMethod(){
}
Call this firstFragmentMethod method from Home_Tab_Fragment using this way
YOUR_fragmentInstance.firstFragmentMethod();
Step 2: Activity to Home_Tab_Fragment:
define an interface like this
public interface IActivityToHomeTabController{
void callFirstFragment();
}
Now implements the IFragmentController in your Home_Tab_Fragment. then you have to implements the callFirstFragment().
#overrride
void callFirstFragment(){
YOUR_fragmentInstance.firstFragmentMethod();
}
Edit 2:
Call fragment using this way
((IFragmentController)YOUR_fragmentInstance).firstFragmentMethod();
Hope this will give you an idea about this topics. For more info visit this answer
First for all, you create interface :
public interface CallBackListener{
void onCallBack();
}
In Fragment
public MyFragment extends Fragment{
private CallBackListener mCallBack;
#Override
public void onAttach(Context context) {
AppCompatActivity activity;
if (context instanceof AppCompatActivity) {
activity = (AppCompatActivity) context;
try {
mCallBack= (CallBackListener ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " class must be implement" +
" OnBackFragmentListener");
}
}
super.onAttach(context);
}
}
Use :
mCallBack.onCallBack();
And in Activity, you must implements interface :
public MyActivity extends AppCompatActivity implements CallBackListener{
#Override
public void onCallBack(){
// Do somethings here...
}
}