i am building a simple recycle view with a custom adapter, i already set the position of all of my elements, but somehow the image of my row the main one is not showing up and i don't know why.
Before i changed the xml it was showing up, so basicly i have my main activity:
public class PlantFeed extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,PlantFeedAdapter.OnItemClickListener {
//initialize fields
String token;
ArrayList<PlantPhotoUser> photos = new ArrayList<>();
VolleyService mVolleyService;
IResult mResultCallback = null;
final String GETREQUEST = "GETCALL";
String connectionTxt;
String URL;
String date;
String lat;
String lon;
String alt;
PlantFeedAdapter plantFeedAdapter;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plant_feed);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
connectionString connection = ((connectionString) getApplicationContext());
connectionTxt = connection.getGlobalVarValue();
URL = connectionTxt + "/fotos";
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(PlantFeed.this,CameraCapture.class);
startActivity(i);
}
});
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.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
recyclerView = (RecyclerView)findViewById(R.id.recycleView2);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
plantFeedAdapter = new PlantFeedAdapter(getApplicationContext(), photos,PlantFeed.this);
recyclerView.setAdapter(plantFeedAdapter);
token = checkForToken();
initVolleyCallback();
mVolleyService = new VolleyService(mResultCallback,this);
mVolleyService.getDataVolley(GETREQUEST,URL,token);
}
void initVolleyCallback(){
mResultCallback = new IResult() {
#Override
public void notifySuccess(String requestType,JSONObject response) {
Log.d("HELLL","hi1");
}
#Override
public void notifySuccess(String requestType, JSONArray response) {
PlantPhotoUser plantPhotoUser;
Log.d("HELLLL","hi");
for (int i=0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
Log.d("objeto",object.toString());
int userId = object.getInt("userId");
Log.d("objeto",String.valueOf(userId));
String username = object.getJSONObject("user").getString("username");
Log.d("objeto",String.valueOf(username));
int plantId = object.getInt("plantId");
Log.d("objeto",String.valueOf(plantId));
String specie = object.getJSONObject("plant").getString("specie");
Log.d("objeto",String.valueOf(specie));
String path = object.getString("image");
Log.d("objeto",String.valueOf(path));
int fotoId = object.getInt("id");
if(object.getString("date") != null){
date = object.getString("date");
}
if(object.getString("lat") != null){
lat = object.getString("lat");
}
if(object.getString("lon") != null){
lon = object.getString("lon");
}
if(object.getString("altitude") != null){
alt = object.getString("altitude");
}
plantPhotoUser = new PlantPhotoUser(fotoId,plantId,userId,path,specie,date,lat,lon,alt,username);
photos.add(plantPhotoUser);
} catch (JSONException e) {
e.printStackTrace();
}
}
plantFeedAdapter.notifyDataSetChanged();
}
#Override
public void notifyError(String requestType,VolleyError error) {
Log.d("FAIL",error.toString());
}
};
}
public String checkForToken() {
SharedPreferences sharedPref = getSharedPreferences("user", MODE_PRIVATE);
String tokenKey = getResources().getString(R.string.token);
String token = sharedPref.getString(getString(R.string.token), tokenKey); // take the token
return token;
}
#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.plant_feed, 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.Perfil) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
Intent i = new Intent(PlantFeed.this,CameraCapture.class);
startActivity(i);
} else if (id == R.id.nav_gallery) {
Intent i = new Intent(PlantFeed.this,PlantFeed.class);
startActivity(i);
} else if (id == R.id.nav_slideshow) {
Intent i = new Intent(PlantFeed.this,FamilyLibrary.class);
startActivity(i);
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onRowClick(int position, String name, int id, View view) {
}
#Override
public void onTitleClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,PhotosForPlant.class);
i.putExtra("plantId",String.valueOf(id));
startActivity(i);
}
#Override
public void onImageClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,PhotosForPlant.class);
i.putExtra("plantId",String.valueOf(id));
startActivity(i);
}
#Override
public void onReportClicked(int position, int id, String name, View clickedview) {
Log.d("HELLLO","HELLOO");
showDialogReport(id,name);
}
#Override
public void onUserIconClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,UserProfile.class);
i.putExtra("userId",id);
startActivity(i);
}
#Override
public void onUsernameClicked(int position, int id, View clickedview) {
Intent i = new Intent(this,UserProfile.class);
i.putExtra("userId",id);
startActivity(i);
}
#Override
public void onAvaliationClicked(int position, int id, String name, View clickedview) {
}
private void showDialogReport(int id, String name) {
Log.d("HELLLO","HELLOO");
AlertDialog.Builder builder = new AlertDialog.Builder(PlantFeed.this);
builder.setTitle(name);
builder.setMessage("Tem a certeza que pretende reportar a fotografia?");
builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//TODO reportar base de dados
}
});
builder.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
and then i have my customer adapter like this:
public class PlantFeedAdapter extends RecyclerView.Adapter<PlantFeedAdapter.ViewHolder> {
private OnItemClickListener listener;
public interface OnItemClickListener {
void onRowClick(int position, String name, int id, View view);
void onTitleClicked(int position, int id, View clickedview);
void onImageClicked(int position,int id, View clickedview);
void onReportClicked(int position, int id,String name, View clickedview);
void onUserIconClicked(int position, int id, View clickedview);
void onUsernameClicked(int position, int id, View clickedview);
void onAvaliationClicked(int position, int id,String name, View clickedview);
}
private ArrayList<PlantPhotoUser> photos;
private Context context;
public PlantFeedAdapter(Context context, ArrayList<PlantPhotoUser> photos, OnItemClickListener listener) {
this.photos = photos;
this.context = context;
this.listener = listener;
}
#Override
public PlantFeedAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.plant_feed_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final PlantFeedAdapter.ViewHolder viewHolder, final int i) {
viewHolder.name.setText(photos.get(i).getSpecie());
viewHolder.username.setText(photos.get(i).getUsernName());
viewHolder.data.setText(photos.get(i).getDate().split("T")[0]);
Log.d("data123",(photos.get(i).getDate().toString()));
String urlFoto = "http://fe1b7efd.ngrok.io/" + photos.get(i).getPath();
if(urlFoto.toLowerCase().contains("public/")){
urlFoto = urlFoto.replace("public/","");
}
viewHolder.userIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onUserIconClicked(viewHolder.getAdapterPosition(), photos.get(i).getUserId(), view);
}
}
});
viewHolder.username.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onUsernameClicked(viewHolder.getAdapterPosition(),photos.get(i).getUserId(), view);
}
}
});
viewHolder.plantImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onImageClicked(viewHolder.getAdapterPosition(), photos.get(i).getIdPlant(), view);
}
}
});
viewHolder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
listener.onTitleClicked(viewHolder.getAdapterPosition(),photos.get(i).getIdPlant(),v);
}
}
});
viewHolder.reportImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
listener.onReportClicked(viewHolder.getAdapterPosition(),photos.get(i).getIdPlant(),photos.get(i).getSpecie(),v);
}
}
});
/*viewHolder.avaliationFoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
listener.onAvaliationClicked(viewHolder.getAdapterPosition(),photos.get(i).getIdPlant(),photos.get(i).getSpecie(),v);
}
}
});*/
Picasso.with(context)
.load(urlFoto)
.resize(300, 300)
.into(viewHolder.plantImg);
}
#Override
public int getItemCount() {
return photos.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView name;
private ImageView userIcon;
private TextView avaliationFoto;
private ImageView plantImg;
private ImageView foto;
private TextView username;
private ImageView reportImage;
private TextView data;
public ViewHolder(View view) {
super(view);
data = (TextView)view.findViewById(R.id.data);
name = (TextView) view.findViewById(R.id.plantName);
userIcon = (ImageView)view.findViewById(R.id.userIcon);
plantImg = (ImageView)view.findViewById(R.id.plantPhoto);;
username = (TextView)view.findViewById(R.id.password);
reportImage = (ImageView)view.findViewById(R.id.cameraForbiden);
}
}
}
finally my row xml, wher i think there is the problem
<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="wrap_content"
android:background="#cfcfcf">
<LinearLayout
android:layout_margin="10dp"
android:background="#ffffff"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.volley.toolbox.NetworkImageView
android:layout_weight="1"
android:layout_width="120dp"
android:layout_height="100dp"
android:padding="0dp"
app:srcCompat="#mipmap/ic_launcher"
android:id="#+id/plantPhoto"
android:background="#c7c7c7"
/>
<LinearLayout
android:layout_weight="20"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/plantName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:padding="15dp"
android:text="TextView"
android:textColor="#000"
android:textSize="20dp" />
<ImageView
android:id="#+id/starIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:gravity="right"
android:src="#drawable/ic_star" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="15dp">
<com.example.afcosta.inesctec.pt.android.Helpers.NexusBoldTextView
android:id="#+id/data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="#+id/cameraForbiden"
android:text="TextView"
android:textColor="#color/base" />
<ImageView
android:id="#+id/cameraForbiden"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:src="#drawable/ic_no_photos" />
<ImageView
android:id="#+id/userIcon"
android:layout_width="15dp"
android:layout_height="15dp"
android:gravity="left"
android:layout_alignParentBottom="true"
android:src="#drawable/ic_user" />
<com.example.afcosta.inesctec.pt.android.Helpers.NexusBoldTextView
android:id="#+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/userIcon"
android:text="Filipe"
android:textColor="#color/base" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
the problem is on this element:
<com.android.volley.toolbox.NetworkImageView
android:layout_weight="1"
android:layout_width="120dp"
android:layout_height="100dp"
android:padding="0dp"
app:srcCompat="#mipmap/ic_launcher"
android:id="#+id/plantPhoto"
android:background="#c7c7c7"
/>
Add centerCrop() with Picasso
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)
Change this lines in Your Adapter and in ViewHolder because type cast is wrong. :
private ImageView plantImg;
plantImg = (ImageView)view.findViewById(R.id.plantPhoto);;
to
private NetworkImageView plantImg;
plantImg= (NetworkImageView) findViewById(R.id
.plantPhoto); then set image .
Edit
`private ImageLoader mImageLoader;
mImageLoader = CustomVolleyRequestQueue.getInstance(this.getApplicationContext())
.getImageLoader();
mImageLoader.get(url, ImageLoader.getImageListener(mNetworkImageView,
R.mipmap.truiton_short, android.R.drawable
.ic_dialog_alert));
mNetworkImageView.setImageUrl(url, mImageLoader);`
use this link http://www.truiton.com/2015/03/android-volley-imageloader-networkimageview-example/ for further guide.
Related
I have a navigation activity. In the file content.xml I have a recyclerview. If I put an EditText in the content.xml the recylerview is displayed, however if I do not put it it is not displayed.
I do not need the EditText field
Here are my code.
content_navegador.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
tools:context="com.example.pablo.pruebasauthproyecto.Activities.Navegador"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_navegador">
<EditText
android:id="#+id/search_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:hint="Buscar Proyectos..."
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:focusable="true"
android:id="#+id/reciclador"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/search_text" />
</android.support.constraint.ConstraintLayout>
Navegador.java
public class Navegador extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
public final static String PROYECTO = "proyecto";
private RecyclerView recycler;
private FirebaseUser fUsr;
private String intereses;
private String claveProy;
private ArrayList<Proyecto> proyectos = new ArrayList<>();
private ArrayList<String> listaIntereses = new ArrayList<>();
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Recursos r;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navegador);
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);
recuperarProyectos ();
}
private void recuperarInteresesUsuario() {
fUsr = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference interesesRef = ref.child("intereses").child(fUsr.getUid());
interesesRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
intereses = dataSnapshot.getValue().toString();
listaIntereses.add(intereses);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void verProyecto(Proyecto proyecto) {
// Log.d("DEPURACIÓN", proyecto.toString());
Intent intent = new Intent(this, FichaProyecto.class);
intent.putExtra(this.PROYECTO, proyecto);
startActivity(intent);
}
private void cargarRecycler() {
// Obtener el Recycler
recycler = (RecyclerView) findViewById(R.id.reciclador);
recycler.setHasFixedSize(true);
ProyectosAdapter adapter = new ProyectosAdapter(proyectos);
adapter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Log.d("DEPURACIÓN" , "Item Pulsado : " + proyectos.get(recycler.getChildAdapterPosition(view)).getNombre());
Proyecto prosel = proyectos.get(recycler.getChildAdapterPosition(view));
verProyecto(prosel);
}
});
recycler.setAdapter(adapter);
// Usar un administrador para LinearLayout
LinearLayoutManager lManager = new LinearLayoutManager(this);
recycler.setLayoutManager(lManager);
}
private void recuperarProyectos () {
DatabaseReference proyectosRef = ref.child("proyectos");
Query consProy = proyectosRef.orderByChild("genero");
consProy.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
claveProy = dataSnapshot.getKey();
final Proyecto p = dataSnapshot.getValue(Proyecto.class);
for (String inter : listaIntereses) {
// Log.d("DEPURACIÓN", inter);
if(p.getGenero().equalsIgnoreCase(inter)) {
// Log.d("DEPURACIÓN", p.toString());
DatabaseReference recursosRef = ref.child("recursos");
Query consRecursos = recursosRef.orderByChild("idProyecto").equalTo(claveProy);
consRecursos.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
r = dataSnapshot.getValue(Recursos.class);
// Log.d("DEPURACIÓN","PROYECTO -> " + p.toString());
p.addRecurso(r);
// Log.d("DEPURACIÓN", "RECURSOS PROYECTO -> " + p.getRecursos().toString());
proyectos.add(p);
// eliminamos elementos repetidos del ArrayList
HashSet<Proyecto> hs = new HashSet<>();
hs.addAll(proyectos);
proyectos.clear();
proyectos.addAll(hs);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
recuperarInteresesUsuario();
cargarRecycler();
}
#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.navegador, 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();
if (id == R.id.crear_proyect) {
startActivity(new Intent(Navegador.this, CrearProyecto.class));
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
} }
ProyectosAdapter.java
public class ProyectosAdapter extends
RecyclerView.Adapter implements
View.OnClickListener {
private List<Proyecto> items;
private View.OnClickListener listener;
public class ProyectosViewHolder extends RecyclerView.ViewHolder {
public ImageView imagen;
public TextView nombre;
public TextView autor;
public TextView genero;
public ProyectosViewHolder(View v) {
super(v);
imagen = (ImageView) v.findViewById(R.id.imagen);
nombre = (TextView) v.findViewById(R.id.nombre);
autor = (TextView) v.findViewById(R.id.autor);
genero = (TextView) v.findViewById(R.id.genero);
}
}
public ProyectosAdapter(List<Proyecto> items) {
this.items = items;
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public ProyectosViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.proyectos_card, viewGroup, false);
v.setOnClickListener(this);
return new ProyectosViewHolder(v);
}
#Override
public void onBindViewHolder(final ProyectosViewHolder viewHolder, int i) {
viewHolder.nombre.setText(items.get(i).getNombre());
viewHolder.autor.setText(items.get(i).getAutor());
viewHolder.genero.setText(items.get(i).getGenero());
Context context = viewHolder.imagen.getContext();
Uri uri = Uri.parse(items.get(i).getRecursos().get(0).getRuta());
Picasso.with(context)
.load(uri)
.resize(355,225)
.centerCrop()
.into(viewHolder.imagen);
}
#Override
public void onClick(View view) {
if(listener != null)
listener.onClick(view);
}
public void setOnClickListener(View.OnClickListener listener) {
this.listener = listener;
} }
Sounds like your constraints are messed up. For example your RecyclerView have toBottomOf="#+id/search_text", so it expects that edit text to present.
Try to remove EditText, and instead of that last line add app:layout_constraintTop_toTopOf="parent".
Your RecyclerView width and height is 0dp.
Try this:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/reciclador"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Remove this line from recyclerview
app:layout_constraintTop_toBottomOf="#+id/search_text"
This is beacuse you have given top to bottom of edittext..
Change it like this:
<android.support.v7.widget.RecyclerView
android:focusable="true"
android:id="#+id/reciclador"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
Put setAdapter after setLayoutManager
There is a situation, I have an activity having recycler view and I have its adapter, there is a model class for three Text Views of a recycler view location,latitude,longitude that comes from database. Now I want the fourth field of recycler view the distance. distance is calculated by another class and return distance in a callback function. where do I initialize the object of that class in recyclerview so that it updates the distance continuously against the lat and long of each item.
Code that return distance for single lat,long
compassManager = new CompassManager(getApplicationContext(), this);
if (isLocationServiceEnabled()) {
Log.i("FloatingViewServie","Location Service Enabled");
// i want to pass latitude and longitude of UserLocations below to
// get distance on each row
compassManager.startNavigating(33.69206669, 73.03208828);
compassManager.getLocation().getLatitude();
compassManager.getLocation().getLongitude();
}
callback method that return continusly updated distance
#Override
public void onDistanceUpdate(float distance) {
//this distance need to be on recyclerview for each row
}
Recyclerview Adapter
public class ActiveLocationsAdapter extends RecyclerView.Adapter<ActiveLocationsAdapter.MyViewHolder> {
public interface OverflowOptions
{
public void edit(int position,UserLocations userLocations);
public void delete();
}
private List<UserLocations> userLocationsList;
FirebaseDatabase database;
DatabaseReference rootRef;
private FirebaseAuth mAuth;
FirebaseUser user;
Context context;
OverflowOptions overflowOptionsCallback;
public ActiveLocationsAdapter(Context context,List<UserLocations> locationsList,OverflowOptions callback) {
this.userLocationsList = locationsList;
database = FirebaseDatabase.getInstance();
rootRef = database.getReference();
mAuth = FirebaseAuth.getInstance();
user = mAuth.getCurrentUser();
this.context=context;
overflowOptionsCallback=callback;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_active_locations, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
// model class that have latitude and longitude for each row
final UserLocations userLocations = userLocationsList.get(position);
Log.i("aaposition",String.valueOf(holder.getAdapterPosition()));
holder.name.setText(userLocations.getName());
// holder.distance.setText(String.valueOf(userLocations.getLatitude()));
// holder.direction.setText(String.valueOf(userLocations.getLongitude()));
holder.overflow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//creating a popup menu
PopupMenu popup = new PopupMenu(context, holder.overflow);
//inflating menu from xml resource
popup.inflate(R.menu.locations_overflow_menu);
//adding click listener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
overflowOptionsCallback.edit(holder.getAdapterPosition(), userLocations);
break;
case R.id.action_delete:
break;
}
return false;
}
});
//displaying the popup
popup.show();
}
});
}
#Override
public int getItemCount() {
return userLocationsList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name, distance, direction;
public ImageView overflow;
public MyViewHolder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.name);
distance = (TextView) view.findViewById(R.id.distance);
direction = (TextView) view.findViewById(R.id.direction);
overflow = (ImageView) view.findViewById(R.id.overflow);
}
}
}
Model Class
public class UserLocations {
String id;
String name;
double latitude;
double longitude;
String status;
public UserLocations() {
}
public UserLocations(String id, String name, double latitude, double longitude, String status) {
this.id=id;
this.name = name;
this.latitude = latitude;
this.longitude = longitude;
this.status = status;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public String getStatus() {return status;}
public void setStatus(String status) {this.status = status;}
}
Row of Recyclerview
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:clickable="true"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical">
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textColor="#color/heading"
android:textSize="16dp"
android:textStyle="bold" />
<TextView
android:id="#+id/distance_lable"
android:layout_below="#id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/subheading"
android:text="Distance : "/>
<!-- To display distance-->
<TextView
android:id="#+id/distance"
android:layout_below="#id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/subheading"
android:layout_toRightOf="#+id/distance_lable"
/>
<TextView
android:layout_below="#id/name"
android:id="#+id/direction_lable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/distance"
android:textColor="#color/subheading"
android:text=" Direction : "/>
<!-- To display direction-->
<TextView
android:id="#+id/direction"
android:layout_below="#id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/subheading"
android:layout_toEndOf="#+id/direction_lable"/>
<ImageButton
android:id="#+id/overflow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="5dp"
android:background="#drawable/ic_more_vert_black_24dp"
/>
</RelativeLayout>
Main Activity that have recyclerview
public class MainActivity extends AppCompatActivity
implements CurrentLocationManager.ResultSupplier,NavigationView.OnNavigationItemSelectedListener,ActiveLocationsAdapter.OverflowOptions{
private static final int CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084;
public static final int REQUEST_FINE_LOCATION = 1;
public static final String TAG= MainActivity.class.getSimpleName();
private PrefManager prefManager;
CurrentLocationManager currentLocationManager;;
private List<UserLocations> userLocationsList = new ArrayList<>();
private RecyclerView recyclerView;
private ActiveLocationsAdapter mAdapter;
FirebaseDatabase database;
DatabaseReference rootRef;
private FirebaseAuth mAuth;
FirebaseUser user;
ProgressDialog progressDoalog;
Context context,interfaceContext;
ImageButton imgBtnSaveLocation;
private double lattitude,longitude;
Switch toggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPermissions(this);
permissionCheck();
context=getApplicationContext();
imgBtnSaveLocation=(ImageButton)findViewById(R.id.main_activity_save_btn) ;
progressDoalog = new ProgressDialog(MainActivity.this);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
toggle=(Switch)findViewById(R.id.active_locations_switch);
mAdapter = new ActiveLocationsAdapter(getApplicationContext(),userLocationsList,this);
prefManager = new PrefManager(this);
prefManager.setFirstTimeLaunch(false);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//database reference pointing to root of database
database = FirebaseDatabase.getInstance();
rootRef = database.getReference();
// gives current authenticated user
mAuth = FirebaseAuth.getInstance();
user = mAuth.getCurrentUser();
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(mAdapter);
progressDoalog.setMessage("Fetching Data. . .");
progressDoalog.show();
// get and update data on View on any change in database
rootRef.child(user.getDisplayName()).child("active_locations").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot noteDataSnapshot : dataSnapshot.getChildren()) {
UserLocations locations = noteDataSnapshot.getValue(UserLocations.class);
if(locations.getStatus().equals("active")) {
if (!contains((ArrayList<UserLocations>) userLocationsList, locations)) {
userLocationsList.add(locations);
}
}
}
mAdapter.notifyDataSetChanged();
progressDoalog.dismiss();
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
}
});
// button click that get current location and save to database
imgBtnSaveLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG,"onclick");
getLocation();
}
});
// turn the tracking on and off
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
Toast.makeText(context, "Toggle on", Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "Toggle off", Toast.LENGTH_SHORT).show();
}
});
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
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.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
public void permissionCheck()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(getApplicationContext())) {
//If the draw over permission is not available open the settings screen
//to grant the permission.
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, CODE_DRAW_OVER_OTHER_APP_PERMISSION);
} else {
}
}
private void requestPermissions(Context context) {
ActivityCompat.requestPermissions((Activity) context,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_FINE_LOCATION);
}
private boolean checkPermissions(Context context) {
if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
requestPermissions(context);
return false;
}
}
#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();
if (id == R.id.nav_active_locations) {
startActivity(new Intent(getApplicationContext(),ActiveLocationsActivity.class));
} else if (id == R.id.nav_tracked_locations) {
startActivity(new Intent(getApplicationContext(),TrackedLocationsActivity.class));
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
AuthUI.getInstance()
.signOut(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
public void onComplete(#NonNull Task<Void> task) {
// user is now signed out
startActivity(new Intent(getApplicationContext(), SignUpActivity.class));
finish(); }
});
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
public void getLocation()
{
currentLocationManager = new CurrentLocationManager(context,this);
currentLocationManager.getUpdatedLocation();
}
/**
* Compares two array list
* #param list
* #param locations
* #return
*/
boolean contains(ArrayList<UserLocations> list, UserLocations locations) {
for (UserLocations item : list) {
if (item.getId().equals(locations.getId())&&item.getName().equals(locations.getName())&&item.getLatitude()==locations.getLatitude()&&item.getLongitude()==locations.getLongitude()&&item.getStatus().equals(locations.getStatus())) {
return true;
}
}
return false;
}
#Override
public void result(double lat, double longi) {
lattitude=lat;
longitude=longi;
Log.i("callback result",String.valueOf(lat)+","+String.valueOf(longi));
}
#Override
public void edit(final int position, final UserLocations userLocations) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.dialog_edit_location_name, null);
dialogBuilder.setView(dialogView);
final EditText rename = (EditText) dialogView.findViewById(R.id.name);
dialogBuilder.setTitle("Rename Location");
//dialogBuilder.setMessage("hello");
dialogBuilder.setPositiveButton("Done", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
renameLocation(userLocations.getName(),rename.getText().toString());
userLocations.setName(rename.getText().toString());
userLocationsList.set(position, userLocations);
}
});
dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//pass
}
});
AlertDialog b = dialogBuilder.create();
b.show();
}
#Override
public void delete() {
}
public void renameLocation(final String name, final String renameLocation) {
Log.i("Interface","renameLocation");
Query renameQuery= rootRef.child(user.getDisplayName()).child("active_locations").orderByChild("name").equalTo(name);
renameQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
String child_name = (String) child.child("name").getValue();
if (child_name.equals(name)){
child.getRef().child("name").setValue(renameLocation);
Log.i("Rename Location","child renamed");
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
I'm trying to change the icon of a button in my recycler view every time the activity starts based off a boolean value in my custom object. I assume this has to be done within the adapter since not every groups button will have the same background.
Below is the code for my recycler view adapter:
public class RecipeListAdapter extends RecyclerView.Adapter<RecipeListAdapter.ViewHolder>{
private List<Recipe> mRecipeSet;
private Button mAddToGroceriesButton;
public RecipeListAdapter(List<Recipe> recipes){
mRecipeSet = recipes;
}
// 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 implements View.OnClickListener {
//This is what will handle what happens when you click a recipe in the recycler view
private TextView mRecipeName;
private TextView mPrepTime;
private TextView mCookTime;
private TextView mServingSize;
private RelativeLayout mRecipeTextSection;
public ViewHolder(View v) {
super(v);
mRecipeName = (TextView) v.findViewById(R.id.recipe_list_recycler_view_recipe_name);
mServingSize = (TextView) v.findViewById(R.id.recipe_list_recycler_view_serving_size);
mPrepTime = (TextView) v.findViewById(R.id.recipe_list_recycler_view_prep_time);
mCookTime = (TextView) v.findViewById(R.id.recipe_list_recycler_view_cook_time);
mRecipeTextSection = (RelativeLayout) v.findViewById(R.id.recycled_item_section_view);
mRecipeTextSection.setOnClickListener(this);
mAddToGroceriesButton = (Button) v.findViewById(R.id.add_to_grocery_list);
mAddToGroceriesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
Recipe recipeToGrocery = mRecipeSet.get(position);
//RecipeDB dbHelper = new RecipeDB(v.getContext());
//dbHelper.addGroceryItem(recipeToGrocery);
if(!recipeToGrocery.isInList()) {
RecipeDB dbHelper = new RecipeDB(v.getContext());
dbHelper.addGroceryItem(recipeToGrocery);
recipeToGrocery.setInList(true);
dbHelper.updateRecipe(recipeToGrocery);
mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
Toast.makeText(v.getContext(), recipeToGrocery.getRecipeName() + " added to grocery list.", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(v.getContext(), "That recipe is already in the list.", Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
public void onClick(View v){
int position = getAdapterPosition();
Intent i = new Intent(v.getContext(), RecipeTextView.class);
Recipe selectedRecipe = mRecipeSet.get(position);
i.putExtra("view_recipe_key", selectedRecipe);
v.getContext().startActivity(i);
}
}
public void add(int position, Recipe item) {
mRecipeSet.add(position, item);
notifyItemInserted(position);
}
public void remove(Recipe item) {
int position = mRecipeSet.indexOf(item);
mRecipeSet.remove(position);
notifyItemRemoved(position);
}
public RecipeListAdapter(ArrayList<Recipe> myRecipeset) {
mRecipeSet = myRecipeset;
}
// Create new views (invoked by the layout manager)
#Override
public RecipeListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_item_recycled, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Recipe recipe = mRecipeSet.get(position);
String recipeName = recipe.getRecipeName();
String prepTime = "Prep Time: " + String.valueOf(recipe.getPrepTime()) + " minutes";
String cookTime = "Cook Time: " + String.valueOf(recipe.getCookTime()) + " minutes";
String servingSize = "Servings: " + String.valueOf(recipe.getServings());
holder.mRecipeName.setText(recipeName);
//Only display values if they are not null
if(recipe.getServings() != null) {
holder.mServingSize.setText(servingSize);
}
if (recipe.getPrepTime() != null) {
holder.mPrepTime.setText(prepTime);
}
if(recipe.getCookTime() != null) {
holder.mCookTime.setText(cookTime);
}
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
if(mRecipeSet != null) {
return mRecipeSet.size();
}
return 0;
}
}
I know how to change the background of the button when it's clicked with
mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
but it's obviously not going to save the state of that button when the activity restarts. I'm just not sure of how to check the boolean value for each group upon activity start up and change the button background accordingly.
I tried using
if(recipe.isInList()){
mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
}
in the onBindViewHolder method but it didn't do anything, and I'm pretty sure that wouldn't be the correct place for it anyways. I know the boolean is working properly since I use it in other places and it works fine.
Here's the relevant XML code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/apk/res/android"
android:layout_margin="7dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:id="#+id/recycled_item_section_view"
android:elevation="30dp"
android:background="#drawable/background_border"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Recipe name"
android:textSize="24dp"
android:textColor="#color/black"
android:id="#+id/recipe_list_recycler_view_recipe_name"
android:paddingBottom="3dp"
android:maxWidth="275dip"
android:singleLine="false"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18dp"
android:textColor="#color/black"
android:layout_below="#id/recipe_list_recycler_view_recipe_name"
android:id="#+id/recipe_list_recycler_view_serving_size"
android:paddingBottom="3dp"/>
<Button
android:layout_width="35dp"
android:layout_height="35dp"
android:background="#mipmap/ic_playlist_add_black_24dp"
android:height="36dp"
android:padding="8dp"
android:layout_alignParentRight="true"
android:id="#+id/add_to_grocery_list"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/recipe_list_recycler_view_serving_size"
android:layout_alignParentLeft="true"
android:textSize="18dp"
android:textColor="#color/black"
android:id="#+id/recipe_list_recycler_view_prep_time"
android:paddingBottom="3dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/recipe_list_recycler_view_prep_time"
android:textSize="18dp"
android:textColor="#color/black"
android:layout_alignParentLeft="true"
android:id="#+id/recipe_list_recycler_view_cook_time"/>
</RelativeLayout>
Recipe class:
public class Recipe implements Parcelable {
//These are all of the qualities a recipe contains, we will create an arraylist of this in the activity
private String mRecipeName;
private int mID;
private String mServings;
private String mPrepTime;
private String mCookTime;
private boolean isInList;
private List<String> mIngredients;
private List<String> mDirections;
public Recipe(){
}
public Recipe(int id, String name, String serving, String prep, String cook, List<String>
ingredientsList, List<String> directionsList, boolean inList){
this.mID = id;
this.mRecipeName = name;
this.mServings = serving;
this.mPrepTime = prep;
this.mCookTime = cook;
this.mIngredients = ingredientsList;
this.mDirections = directionsList;
this.isInList = inList;
}
public Recipe(String name, String serving, String prep, String cook, List<String>
ingredientsList, List<String> directionsList, boolean inList){
this.mRecipeName = name;
this.mServings = serving;
this.mPrepTime = prep;
this.mCookTime = cook;
this.mIngredients = ingredientsList;
this.mDirections = directionsList;
this.isInList = inList;
}
public String getRecipeName() {
return mRecipeName;
}
public int getID() {
return mID;
}
public void setID(int id){
mID = id;
}
public String getServings() {
return mServings;
}
public String getPrepTime() {
return mPrepTime;
}
public void setRecipeName(String recipeName) {
mRecipeName = recipeName;
}
public void setServingSize(String servings) {
mServings = servings;
}
public void setPrepTime(String prepTime) {
mPrepTime = prepTime;
}
public void setServings(String servings) {
mServings = servings;
}
public List<String> getIngredients() {
return mIngredients;
}
public List<String> getDirections() {
return mDirections;
}
public String getCookTime() {
return mCookTime;
}
public void setCookTime(String cookTime) {
mCookTime = cookTime;
}
public void setIngredients(List<String> ingredients) {
mIngredients = ingredients;
}
public void setDirections(List<String> directions) {
mDirections = directions;
}
public boolean isInList() {
return isInList;
}
public void setInList(boolean inList) {
isInList = inList;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.mRecipeName);
dest.writeInt(this.mID);
dest.writeString(this.mServings);
dest.writeString(this.mPrepTime);
dest.writeString(this.mCookTime);
dest.writeByte(this.isInList ? (byte) 1 : (byte) 0);
dest.writeStringList(this.mIngredients);
dest.writeStringList(this.mDirections);
}
protected Recipe(Parcel in) {
this.mRecipeName = in.readString();
this.mID = in.readInt();
this.mServings = in.readString();
this.mPrepTime = in.readString();
this.mCookTime = in.readString();
this.isInList = in.readByte() != 0;
this.mIngredients = in.createStringArrayList();
this.mDirections = in.createStringArrayList();
}
public static final Creator<Recipe> CREATOR = new Creator<Recipe>() {
#Override
public Recipe createFromParcel(Parcel source) {
return new Recipe(source);
}
#Override
public Recipe[] newArray(int size) {
return new Recipe[size];
}
};
}
And main activity class that uses the adapter:
public class RecipeList extends AppCompatActivity{
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private int REQUEST_CODE=1;
private Button mNavigateGroceryButton;
RecipeDB dbHelper = new RecipeDB(this);
List<Recipe> recipes;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recipes = dbHelper.getAllRecipes();
setContentView(R.layout.activity_recipe_list);
mRecyclerView = (RecyclerView) findViewById(R.id.list_recycler_view);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecipeListAdapter(recipes);
mRecyclerView.setAdapter(mAdapter);
mNavigateGroceryButton = (Button) findViewById(R.id.navigate_to_groceries_button_list_view);
mNavigateGroceryButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(RecipeList.this, ExpandableListViewActivity.class);
//Log.d("Navigate", "navigate pressed" );
startActivity(i);
}
});
}
#Override
public void onBackPressed() {
}
public boolean onOptionsItemSelected(MenuItem item){
//Handles menu buttons
switch (item.getItemId()){
case R.id.recipe_list_add_recipe_actionbar_button:
//This button creates a new empty Recipe object and passes it to the EditRecipe class
//The Recipe object is passed as a parcelable
Recipe passedRecipe = new Recipe();
Intent i = new Intent(RecipeList.this, EditRecipe.class);
i.putExtra("passed_recipe_key", (Parcelable) passedRecipe);
startActivityForResult(i, REQUEST_CODE);
return true;
default:
Log.d("Name,", "default called");
return super.onOptionsItemSelected(item);
}
}
public void addNewReRecipe(Recipe recipe){
dbHelper.addRecipe(recipe);
recipes = dbHelper.getAllRecipes();
mAdapter = new RecipeListAdapter(recipes);
mRecyclerView.setAdapter(mAdapter);
}
//Makes the menu bar appear as it is in the action_bar_recipe_list_buttons menu layout file
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_bar_recipe_list_buttons, menu);
return true;
}
//This code is called after creating a new recipe. This is only for creating, and not editing.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE){
if(resultCode == Activity.RESULT_OK) {
Recipe createdRecipe = data.getExtras().getParcelable("recipe_key");
addNewReRecipe(createdRecipe);
}
}
}
}
Looks like you need to declare your button at the top of your ViewHolder with your other views. So move the declaration from the top of your adapter:
private Button mAddToGroceriesButton;
Then in your onBindViewHolder method you can get a reference to your button through the holder and set the background:
if(recipe.isInList()) {
holder.mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
}
Try this,
public class RecipeListAdapter extends RecyclerView.Adapter<RecipeListAdapter.ViewHolder>{
private List<Recipe> mRecipeSet;
private Button mAddToGroceriesButton;
public RecipeListAdapter(List<Recipe> recipes){
mRecipeSet = recipes;
}
// 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 implements View.OnClickListener {
//This is what will handle what happens when you click a recipe in the recycler view
private TextView mRecipeName;
private TextView mPrepTime;
private TextView mCookTime;
private TextView mServingSize;
private RelativeLayout mRecipeTextSection;
public ViewHolder(View v) {
super(v);
mRecipeName = (TextView) v.findViewById(R.id.recipe_list_recycler_view_recipe_name);
mServingSize = (TextView) v.findViewById(R.id.recipe_list_recycler_view_serving_size);
mPrepTime = (TextView) v.findViewById(R.id.recipe_list_recycler_view_prep_time);
mCookTime = (TextView) v.findViewById(R.id.recipe_list_recycler_view_cook_time);
mRecipeTextSection = (RelativeLayout) v.findViewById(R.id.recycled_item_section_view);
mAddToGroceriesButton = (Button) v.findViewById(R.id.add_to_grocery_list);
}
}
public void add(int position, Recipe item) {
mRecipeSet.add(position, item);
notifyItemInserted(position);
}
public void remove(Recipe item) {
int position = mRecipeSet.indexOf(item);
mRecipeSet.remove(position);
notifyItemRemoved(position);
}
public RecipeListAdapter(ArrayList<Recipe> myRecipeset) {
mRecipeSet = myRecipeset;
}
// Create new views (invoked by the layout manager)
#Override
public RecipeListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_item_recycled, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Recipe recipe = mRecipeSet.get(position);
String recipeName = recipe.getRecipeName();
String prepTime = "Prep Time: " + String.valueOf(recipe.getPrepTime()) + " minutes";
String cookTime = "Cook Time: " + String.valueOf(recipe.getCookTime()) + " minutes";
String servingSize = "Servings: " + String.valueOf(recipe.getServings());
holder.mRecipeName.setText(recipeName);
//Only display values if they are not null
if(recipe.getServings() != null) {
holder.mServingSize.setText(servingSize);
}
if (recipe.getPrepTime() != null) {
holder.mPrepTime.setText(prepTime);
}
if(recipe.getCookTime() != null) {
holder.mCookTime.setText(cookTime);
}
mRecipeTextSection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
Intent i = new Intent(v.getContext(), RecipeTextView.class);
Recipe selectedRecipe = mRecipeSet.get(position);
i.putExtra("view_recipe_key", selectedRecipe);
v.getContext().startActivity(i);
});
Recipe recipeToGrocery = mRecipeSet.get(position);
if(!recipeToGrocery.isInList()) {
mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
}
else{
mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_26dp);//set another image
}
mAddToGroceriesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
Recipe recipeToGrocery = mRecipeSet.get(position);
//RecipeDB dbHelper = new RecipeDB(v.getContext());
//dbHelper.addGroceryItem(recipeToGrocery);
if(!recipeToGrocery.isInList()) {
RecipeDB dbHelper = new RecipeDB(v.getContext());
dbHelper.addGroceryItem(recipeToGrocery);
recipeToGrocery.setInList(true);
dbHelper.updateRecipe(recipeToGrocery);
notifyDataSetChanged();
}
else {
Toast.makeText(v.getContext(), "That recipe is already in the list.", Toast.LENGTH_SHORT).show();
}
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
if(mRecipeSet != null) {
return mRecipeSet.size();
}
return 0;
}
}
Recyclerview doesnt call any Adapter method :onBindViewHolder,onCreateViewHolder therefor the adapter is empty
here is my code :
public class PostsFragment extends Fragment {
public static final String TAG = "PostsFragment";
private static final String KEY_LAYOUT_POSITION = "layoutPosition";
private static final String KEY_TYPE = "type";
public static final int TYPE_HOME = 1001;
public static final int TYPE_FEED = 1002;
private int mRecyclerViewPosition = 0;
private OnPostSelectedListener mListener;
private RecyclerView mRecyclerView;
private RecyclerView.Adapter<PostViewHolder> mAdapter;
public PostsFragment() {
// Required empty public constructor
}
public static PostsFragment newInstance(int type) {
PostsFragment fragment = new PostsFragment();
Bundle args = new Bundle();
args.putInt(KEY_TYPE, type);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_posts, container, false);
rootView.setTag(TAG);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
if (savedInstanceState != null) {
// Restore saved layout manager type.
mRecyclerViewPosition = (int) savedInstanceState
.getSerializable(KEY_LAYOUT_POSITION);
mRecyclerView.scrollToPosition(mRecyclerViewPosition);
// TODO: RecyclerView only restores position properly for some tabs.
}
switch (getArguments().getInt(KEY_TYPE)) {
case TYPE_HOME:
Log.d(TAG, "Restoring recycler view position (following): " + mRecyclerViewPosition);
FirebaseUtil.getCurrentUserRef().child("following").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(final DataSnapshot followedUserSnapshot, String s) {
String followedUserId = followedUserSnapshot.getKey();
String lastKey = "";
if (followedUserSnapshot.getValue() instanceof String) {
lastKey = followedUserSnapshot.getValue().toString();
}
Log.d(TAG, "followed user id: " + followedUserId);
Log.d(TAG, "last key: " + lastKey);
FirebaseUtil.getPeopleRef().child(followedUserId).child("posts")
.orderByKey().startAt(lastKey).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(final DataSnapshot postSnapshot, String s) {
HashMap<String, Object> addedPost = new HashMap<String, Object>();
addedPost.put(postSnapshot.getKey(), true);
FirebaseUtil.getFeedRef().child(FirebaseUtil.getCurrentUserId())
.updateChildren(addedPost).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
FirebaseUtil.getCurrentUserRef().child("following")
.child(followedUserSnapshot.getKey())
.setValue(postSnapshot.getKey());
}
});
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
FirebaseUtil.getFeedRef().child(FirebaseUtil.getCurrentUserId())
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<String> postPaths = new ArrayList<>();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Log.d(TAG, "adding post key: " + snapshot.getKey());
postPaths.add(snapshot.getKey());
}
mAdapter = new FirebasePostQueryAdapter(postPaths,
new FirebasePostQueryAdapter.OnSetupViewListener() {
#Override
public void onSetupView(PostViewHolder holder, Post post, int position, String postKey) {
setupPost(holder, post, position, postKey);
}
});
}
#Override
public void onCancelled(DatabaseError firebaseError) {
}
});
break;
default:
throw new RuntimeException("Illegal post fragment type specified.");
}
mRecyclerView.setAdapter(mAdapter);
}
private FirebaseRecyclerAdapter<Post, PostViewHolder> getFirebaseRecyclerAdapter(Query query) {
return new FirebaseRecyclerAdapter<Post, PostViewHolder>(
Post.class, R.layout.post_item, PostViewHolder.class, query) {
#Override
public void populateViewHolder(final PostViewHolder postViewHolder,
final Post post, final int position) {
setupPost(postViewHolder, post, position, null);
}
#Override
public void onViewRecycled(PostViewHolder holder) {
super.onViewRecycled(holder);
}
};
}
private void setupPost(final PostViewHolder postViewHolder, final Post post, final int position, final String inPostKey) {
postViewHolder.setPhoto(post.getThumb_url());
postViewHolder.setText(post.getText());
postViewHolder.setTimestamp(DateUtils.getRelativeTimeSpanString(
(long) post.getTimestamp()).toString());
final String postKey;
if (mAdapter instanceof FirebaseRecyclerAdapter) {
postKey = ((FirebaseRecyclerAdapter) mAdapter).getRef(position).getKey();
} else {
postKey = inPostKey;
}
Author author = post.getAuthor();
postViewHolder.setAuthor(author.getFull_name(), author.getUid());
postViewHolder.setIcon(author.getProfile_picture(), author.getUid());
ValueEventListener likeListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
postViewHolder.setNumLikes(dataSnapshot.getChildrenCount());
if (dataSnapshot.hasChild(FirebaseUtil.getCurrentUserId())) {
postViewHolder.setLikeStatus(PostViewHolder.LikeStatus.LIKED, getActivity());
} else {
postViewHolder.setLikeStatus(PostViewHolder.LikeStatus.NOT_LIKED, getActivity());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
FirebaseUtil.getLikesRef().child(postKey).addValueEventListener(likeListener);
postViewHolder.mLikeListener = likeListener;
postViewHolder.setPostClickListener(new PostViewHolder.PostClickListener() {
#Override
public void showComments() {
Log.d(TAG, "Comment position: " + position);
mListener.onPostComment(postKey);
}
#Override
public void toggleLike() {
Log.d(TAG, "Like position: " + position);
mListener.onPostLike(postKey);
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
if (mAdapter != null && mAdapter instanceof FirebaseRecyclerAdapter) {
((FirebaseRecyclerAdapter) mAdapter).cleanup();
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save currently selected layout manager.
int recyclerViewScrollPosition = getRecyclerViewScrollPosition();
Log.d(TAG, "Recycler view scroll position: " + recyclerViewScrollPosition);
savedInstanceState.putSerializable(KEY_LAYOUT_POSITION, recyclerViewScrollPosition);
super.onSaveInstanceState(savedInstanceState);
}
private int getRecyclerViewScrollPosition() {
int scrollPosition = 0;
// TODO: Is null check necessary?
if (mRecyclerView != null && mRecyclerView.getLayoutManager() != null) {
scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
}
return scrollPosition;
}
/**
* 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/>
*/
public interface OnPostSelectedListener {
void onPostComment(String postKey);
void onPostLike(String postKey);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnPostSelectedListener) {
mListener = (OnPostSelectedListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnPostSelectedListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
the adapter class
public class FirebasePostQueryAdapter extends RecyclerView.Adapter<PostViewHolder> {
private final String TAG = "PostQueryAdapter";
private List<String> mPostPaths;
private OnSetupViewListener mOnSetupViewListener;
public FirebasePostQueryAdapter(List<String> paths, OnSetupViewListener onSetupViewListener) {
if (paths == null || paths.isEmpty()) {
mPostPaths = new ArrayList<>();
} else {
mPostPaths = paths;
}
mOnSetupViewListener = onSetupViewListener;
}
#Override
public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.post_item, parent, false);
return new PostViewHolder(v);
}
public void setPaths(List<String> postPaths) {
mPostPaths = postPaths;
notifyDataSetChanged();
}
public void addItem(String path) {
mPostPaths.add(path);
notifyItemInserted(mPostPaths.size());
}
#Override
public void onBindViewHolder(final PostViewHolder holder, int position) {
DatabaseReference ref = FirebaseUtil.getPostsRef().child(mPostPaths.get(position));
// TODO: Fix this so async event won't bind the wrong view post recycle.
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
Log.d(TAG, "post key: " + dataSnapshot.getKey());
mOnSetupViewListener.onSetupView(holder, post, holder.getAdapterPosition(),
dataSnapshot.getKey());
}
#Override
public void onCancelled(DatabaseError firebaseError) {
Log.e(TAG, "Error occurred: " + firebaseError.getMessage());
}
};
ref.addValueEventListener(postListener);
holder.mPostRef = ref;
holder.mPostListener = postListener;
}
#Override
public void onViewRecycled(PostViewHolder holder) {
super.onViewRecycled(holder);
holder.mPostRef.removeEventListener(holder.mPostListener);
}
#Override
public int getItemCount() {
return mPostPaths.size();
}
public interface OnSetupViewListener {
void onSetupView(PostViewHolder holder, Post post, int position, String postKey);
}
}
the main class
public class FeedsActivity extends AppCompatActivity implements PostsFragment.OnPostSelectedListener {
private static final String TAG = "FeedsActivity";
private FloatingActionButton mFab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feeds);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ViewPager viewPager = (ViewPager) findViewById(R.id.feeds_view_pager);
FeedsPagerAdapter adapter = new FeedsPagerAdapter(getSupportFragmentManager());
adapter.addFragment(PostsFragment.newInstance(PostsFragment.TYPE_HOME), "HOME");
adapter.addFragment(PostsFragment.newInstance(PostsFragment.TYPE_FEED), "FEED");
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(1);
TabLayout tabLayout = (TabLayout) findViewById(R.id.feeds_tab_layout);
tabLayout.setupWithViewPager(viewPager);
mFab = (FloatingActionButton) findViewById(R.id.fab);
mFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null || user.isAnonymous()) {
Toast.makeText(FeedsActivity.this, "You must sign-in to post.", Toast.LENGTH_SHORT).show();
return;
}
Intent newPostIntent = new Intent(FeedsActivity.this, NewPostActivity.class);
startActivity(newPostIntent);
}
});
}
#Override
public void onPostComment(String postKey) {
Intent intent = new Intent(this, CommentsActivity.class);
intent.putExtra(CommentsActivity.POST_KEY_EXTRA, postKey);
startActivity(intent);
}
#Override
public void onPostLike(final String postKey) {
final String userKey = FirebaseUtil.getCurrentUserId();
final DatabaseReference postLikesRef = FirebaseUtil.getLikesRef();
postLikesRef.child(postKey).child(userKey).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// User already liked this post, so we toggle like off.
postLikesRef.child(postKey).child(userKey).removeValue();
} else {
postLikesRef.child(postKey).child(userKey).setValue(ServerValue.TIMESTAMP);
}
}
#Override
public void onCancelled(DatabaseError firebaseError) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_feeds, 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) {
// TODO: Add settings screen.
return true;
} else if (id == R.id.action_profile) {
startActivity(new Intent(this, ProfileActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
class FeedsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public FeedsPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
activity_feeds.xml
<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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:layout_scrollFlags="scroll|enterAlways|snap"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.TabLayout
android:id="#+id/feeds_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/feeds_view_pager"
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="#android:drawable/ic_input_add"
android:tint="#android:color/white"/>
post_item.xml
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="8dp"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:padding="10dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/post_author_icon"
android:layout_width="#dimen/post_author_icon_size"
android:layout_height="#dimen/post_author_icon_size"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<TextView
android:id="#+id/post_author_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/post_author_icon"
android:layout_marginLeft="4dp"
style="#style/Base.TextAppearance.AppCompat.Title"
android:textColor="#android:color/primary_text_light_nodisable"
android:text="Unknown"/>
<TextView
android:id="#+id/post_timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:textColor="#android:color/primary_text_light"
android:textSize="18sp" />
</RelativeLayout>
<ImageView
android:id="#+id/post_photo"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/post_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="false"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:textColor="#android:color/primary_text_light"
android:textSize="16sp"
android:ellipsize="end" />
<TextView
android:id="#+id/post_num_likes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:textColor="#android:color/secondary_text_light"
android:textSize="14sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp">
<ImageView
android:id="#+id/post_like_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/heart_full"/>
<ImageView
android:id="#+id/post_comment_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="6dp"
android:layout_toRightOf="#id/post_like_icon"
android:src="#drawable/ic_chat_24dp"
android:tint="#color/blue_grey_500"/>
</RelativeLayout>
</LinearLayout>
fragment_posts.xml
<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=".PostsFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
You are setting the adapter on the recyclerview before the adapter has been initialised. Try:
mAdapter = new FirebasePostQueryAdapter(postPaths,
new FirebasePostQueryAdapter.OnSetupViewListener() {
#Override
public void onSetupView(PostViewHolder holder, Post post, int position, String postKey) {
setupPost(holder, post, position, postKey);
}
});
mRecyclerView.setAdapter(mAdapter);
I have two activities, one shows the movie list, and the other shows movie details. I have a shared element transition on a movie's poster. It works fine when I use with linearlayoutmanager, but when I use a gridLayoutManager for the recyclerView, after I press back button get back from the detail activity, the other image becomes blank as shown here.image
In this picture, I clicked on x-men's movie poster, but the image next to it becomes blank.
I have set a unique transitionName for every item. It's probably not the reason.
this is my activity
public class MainActivity extends AppCompatActivity implements MovieGridAdapter.OnItemClickListener {
private MovieGridAdapter mAdapter;
private int mPosition;
private Toolbar mToolbar;
private RecyclerView mMovieGridLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
PreferenceManager.setDefaultValues(this, R.xml.pref_general, false);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mMovieGridLayout = (RecyclerView) findViewById(R.id.movie_grid);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
mMovieGridLayout.setLayoutManager(gridLayoutManager);
mAdapter = new MovieGridAdapter();
mAdapter.setOnItemClickListener(this);
mMovieGridLayout.setAdapter(mAdapter);
}
#Override
protected void onStart() {
super.onStart();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String sortBy = sharedPreferences.getString(getString(R.string.sort_by_key), getString(R.string.popularity));
MoviePuller.getMoviePuller().discoverMovies(sortBy);
}
#Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent intent = new Intent(this, SettingActivity.class);
startActivity(intent);
return true;
} else if (id == R.id.action_refresh) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String sortBy = sharedPreferences.getString(getString(R.string.sort_by_key), getString(R.string.popularity));
MoviePuller.getMoviePuller().discoverMovies(sortBy);
}
return super.onOptionsItemSelected(item);
}
#Subscribe
public void onPullSuccessEvent(Integer eventId) {
if (eventId == EventId.PULL_SUCCESS) {
mAdapter.notifyDataSetChanged();
}
}
#Override
public void onItemClick(View v, int position) {
mPosition = position;
Intent intent = new Intent(this, MovieDetailActivity.class);
ImageView imageView = (ImageView) v.findViewById(R.id.poster);
TextView title = (TextView) v.findViewById(R.id.title);
ActivityOptionsCompat scaleUpAnimationOptions = createScaleUpAnimationOptions(imageView,title);
intent.putExtra(Constants.POSITION, position);
ActivityCompat.startActivity(this, intent, scaleUpAnimationOptions.toBundle());
}
private ActivityOptionsCompat createScaleUpAnimationOptions(View view, View view2) {
Pair<View,String> pair = new Pair<>(view,view.getTransitionName());
Pair<View,String> pair2 = new Pair<>(view2,view2.getTransitionName());
Pair<View,String> pair3 = new Pair<View, String>(mToolbar,mToolbar.getTransitionName());
// View statusBar = getWindow().getDecorView().findViewById(android.R.id.navigationBarBackground);
// Pair<View,String> pair4 = new Pair<>(statusBar, ViewCompat.getTransitionName(statusBar));
return ActivityOptionsCompat.makeSceneTransitionAnimation(this,pair,pair2,pair3);
}
}
this is my adapter
public class MovieGridAdapter extends RecyclerView.Adapter<MovieGridAdapter.MyHolder> {
private JSONArray mMovies;
private OnItemClickListener mOnItemClickListener;
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CardView cardView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_movie, parent, false);
return new MyHolder(cardView,mOnItemClickListener);
}
#Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.bind(position);
}
#Override
public int getItemCount() {
mMovies = MoviePuller.getMovies();
if (mMovies != null) {
return mMovies.length();
}
return 0;
}
public interface OnItemClickListener {
void onItemClick(View v, int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView mPoster;
public TextView mTitle;
private OnItemClickListener mOnItemClickListener;
public MyHolder(View itemView, OnItemClickListener listener) {
super(itemView);
mOnItemClickListener = listener;
mTitle = (TextView) itemView.findViewById(R.id.title);
mPoster = (ImageView) itemView.findViewById(R.id.poster);
itemView.setOnClickListener(this);
}
public void bind(int position) {
if (mMovies != null) {
try {
JSONObject movie = mMovies.getJSONObject(position);
String title = movie.getString(Constants.KEY_TITLE);
String posterPath = movie.getString(Constants.KEY_POSTER_PATH);
Picasso.with(itemView.getContext()).
load(MoviePuller.POSTER_BASE_URL + posterPath).into(mPoster);
mPoster.setTransitionName(itemView.getResources().getString(R.string.transition_poster) + position);
mTitle.setText(title);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(v, getAdapterPosition());
}
}
}
}
this is my detail activity
public class MovieDetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_moviedetail);
Slide slide = new Slide(Gravity.BOTTOM);
slide.addTarget(R.id.divider);
slide.addTarget(R.id.vote_average);
slide.addTarget(R.id.release_date);
slide.addTarget(R.id.plot_synopsis);
slide.addTarget(R.id.rating);
slide.addTarget(R.id.divider1);
getWindow().setEnterTransition(slide);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
ImageView poster = (ImageView) findViewById(R.id.poster);
TextView tvTitle = (TextView) findViewById(R.id.title);
RatingBar voteAverage = (RatingBar) findViewById(R.id.vote_average);
TextView tvReleaseDate = (TextView) findViewById(R.id.release_date);
TextView tvPlotSynopsis = (TextView) findViewById(R.id.plot_synopsis);
TextView tvRating = (TextView) findViewById(R.id.rating);
int position = getIntent().getIntExtra(Constants.POSITION, -1);
poster.setTransitionName(getString(R.string.transition_poster) + position);
JSONArray movies = MoviePuller.getMovies();
if(movies != null && movies.length() > position) {
try {
JSONObject movie = movies.getJSONObject(position);
String title = movie.getString(Constants.KEY_TITLE);
String poster_path = movie.getString(Constants.KEY_POSTER_PATH);
String release_date = movie.getString(Constants.KEY_RELEASE_DATE);
String vote_average = movie.getString(Constants.KEY_VOTE_AVERAGE);
String overview = movie.getString(Constants.KEY_OVERVIEW);
String id = movie.getString(Constants.KEY_ID);
MoviePuller.getMoviePuller().getTrailers(id);
MoviePuller.getMoviePuller().getReviews(id);
toolbar.setTitle(title);
setSupportActionBar(toolbar);
Picasso.with(this).load(MoviePuller.POSTER_BASE_URL+poster_path).into(poster);
tvTitle.setText(title);
tvReleaseDate.setText(release_date);
tvPlotSynopsis.setText(overview);
voteAverage.setRating(Float.parseFloat(vote_average)/2);
tvRating.setText(vote_average);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Subscribe
public void onEvent(EventId eventId){
if(eventId.mId == EventId.GET_TRAILER_SUCCESS){
JSONArray trailerArray = (JSONArray) eventId.mEventObject;
}else if(eventId.mId == EventId.GET_REVIEW_SUCCESS){
JSONArray reviewArray = (JSONArray) eventId.mEventObject;
}
}
}
the recyclerView xml is like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".activities.MainActivity"
tools:showIn="#layout/activity_main">
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/movie_grid"/>
</RelativeLayout>
What should i do to avoid this?
i record a gif
I guess the problem is with the way you are passing positions of the views between DetailActivity and the MainActivity.
In MainActivity onItemClick() method replace this
intent.putExtra(Constants.POSITION, position);
with this
Bundle bundle = new Bundle();
bundle.putInt(Constants.POSITION, position);
intent.putExtras(bundle);
And in DetailActivity replace this
int position = getIntent().getIntExtra(Constants.POSITION, -1);
with this
int position = getIntent().getExtras().getInt(Constants.POSITION);
Also, what is itemView in MyHolder class, bind() method. You need to pass context to the adapter and use that.
Create this constructor in MovieGridAdapter :
public MovieGridAdapter(Context context) {
this.context = context;
}
and In bind() method replace occurences of itemView:
Picasso.with(context).load(MoviePuller.POSTER_BASE_URL + posterPath).into(mPoster);
mPoster.setTransitionName(context.getString(R.string.transition_poster) + position);
Initialize MovieGridAdapter in MainActivity in this way:
mAdapter = new MovieGridAdapter(this);