I have checked several times the name of my layout RecyclerView as I show on other StackOverflow questions but it is correct. The error of the logcat is this:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.selfcial/com.example.selfcial.Models.MessageActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.LinearLayoutManager.setStackFromEnd(boolean)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3308)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3457)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2044)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7562)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.LinearLayoutManager.setStackFromEnd(boolean)' on a null object reference
at com.example.selfcial.Models.MessageActivity.onCreate(MessageActivity.java:69)
at android.app.Activity.performCreate(Activity.java:7893)
at android.app.Activity.performCreate(Activity.java:7880)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3283)
This is my my MessageActivity:
package com.example.selfcial.Models;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.selfcial.Adapters.MessageAdapter;
import com.example.selfcial.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MessageActivity extends AppCompatActivity {
TextView username;
ImageView profile;
RecyclerView recyclerViewy;
EditText sendMsg;
ImageButton sendBtn;
FirebaseUser firebaseUser;
DatabaseReference reference;
Intent intent;
MessageAdapter messageAdapter;
List<Chat> chats;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
profile = findViewById(R.id.imageview_profile);
username = findViewById(R.id.usernameLogin);
sendMsg = findViewById(R.id.writeMsg);
sendBtn = findViewById(R.id.sendBtn);
//RecyclerViewChat
recyclerView.findViewById(R.id.recycler_view_chat);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
intent = getIntent();
String id = intent.getStringExtra("id");
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("users").child(id);
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Convert edittext to string
String msg = sendMsg.getText().toString();
//Send message
if (!msg.equals("")) {
sendMessage(firebaseUser.getUid(), id, msg);
} else {
Toast.makeText(MessageActivity.this, "It's an empty message", Toast.LENGTH_SHORT).show();
}
sendMsg.setText("");
}
});
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Users user = snapshot.getValue(Users.class);
username.setText(user.getUsername());
if (user.getImageUrl().equals("default")) {
profile.setImageResource(R.drawable.avatar);
} else {
Glide.with(MessageActivity.this)
.load(user.getImageUrl())
.into(profile);
}
readMessages(firebaseUser.getUid(), id, user.getImageUrl());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void sendMessage(String sender, String receiver, String message) {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("sender", sender);
hashMap.put("receiver", receiver);
hashMap.put("message", message);
reference.child("chats").push().setValue(hashMap);
}
private void readMessages(String myid, String id, String imgUrl) {
chats = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("chats");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
chats.clear();
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
Chat chat = snapshot1.getValue(Chat.class);
if (chat.getReceiver().equals(myid) && chat.getSender().equals(id) ||
chat.getReceiver().equals(id) && chat.getSender().equals(myid)) {
chats.add(chat);
}
messageAdapter = new MessageAdapter(MessageActivity.this, chats, imgUrl);
recyclerView.setAdapter(messageAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
This is the MessageAdapter:
ackage com.example.selfcial.Adapters;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.selfcial.Models.Chat;
import com.example.selfcial.Models.MessageActivity;
import com.example.selfcial.Models.Users;
import com.example.selfcial.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import java.util.List;
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
private Context context;
private List<Chat> mChat;
private String imgUrl;
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
//Firebase
FirebaseUser firebaseUser;
//Constructor
public MessageAdapter(Context context, List<Chat> mChat, String imgUrl) {
this.context = context;
this.mChat = mChat;
this.imgUrl = imgUrl;
}
#NonNull
#Override
public MessageAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
if (viewType == MSG_TYPE_RIGHT) {
view = LayoutInflater.from(context).inflate(R.layout.item_sent,
parent,
false);
}else {
view = LayoutInflater.from(context).inflate(R.layout.item_received,
parent,
false);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MessageAdapter.ViewHolder holder, int position) {
Chat chat = mChat.get(position);
holder.show_message.setText(chat.getMessage());
if (imgUrl.equals("default")) {
holder.profile_image.setImageResource(R.drawable.avatar);
}else {
Glide.with(context)
.load(imgUrl)
.into(holder.profile_image);
}
}
#Override
public int getItemCount() {
return mChat.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView show_message;
private ImageView profile_image;
public ViewHolder(#NonNull View itemView) {
super(itemView);
show_message = itemView.findViewById(R.id.message);
profile_image = itemView.findViewById(R.id.profileImgReceive);
}
}
#Override
public int getItemViewType(int position) {
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (mChat.get(position).getSender().equals(firebaseUser.getUid())) {
return MSG_TYPE_RIGHT;
} else {
return MSG_TYPE_LEFT;
}
}
}
And this is the activity_message.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Models.MessageActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/imageview_profile"
android:layout_width="40dp"
android:layout_height="40dp"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="28dp"
tools:srcCompat="#drawable/avatar" />
<TextView
android:id="#+id/usernameLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username"
android:textColor="#color/white"
android:layout_marginLeft="23dp" />
</androidx.appcompat.widget.Toolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_chat"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#F8E1E1"
app:layout_constraintBottom_toTopOf="#+id/cardView5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar" />
<androidx.cardview.widget.CardView
android:id="#+id/cardView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageButton
android:id="#+id/sendVoice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:background="#android:color/transparent"
android:contentDescription="TODO"
app:srcCompat="#drawable/ic_mic" />
<ImageButton
android:id="#+id/photoBtn"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="#00FFFFFF"
android:scrollbarThumbHorizontal="#color/black"
android:scrollbarThumbVertical="#color/black"
app:srcCompat="#drawable/ic_baseline_camera_alt_24" />
<ImageButton
android:id="#+id/gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="#android:color/transparent"
app:srcCompat="#drawable/ic_gallery" />
<EditText
android:id="#+id/writeMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginBottom="0dp"
android:layout_weight="1"
android:background="#drawable/msg_shape"
android:ems="10"
android:hint="Bb"
android:inputType="textCapSentences"
android:padding="5dp" />
<ImageButton
android:id="#+id/sendBtn"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="#00FFFFFF"
android:scrollbarThumbHorizontal="#color/black"
android:scrollbarThumbVertical="#color/black"
app:srcCompat="#drawable/ic_send" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
Is the error occured by a mistake on the MessageAdapter or is it a bug somewhere else? I also tried to change LinearLayoutManager line to LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); but this didn't work too.
You call findViewById() here:
recyclerView.findViewById(R.id.recycler_view_chat);
But you are calling the findViewById() method on your recyclerView variable, not assigning the result of your Activity's findViewById() to your variable, so your variable is always null.
recyclerView = findViewById(R.id.recycler_view_chat);
Related
I am trying to display my contact list for my mobile application. I have already connected the database and I figured that there is no problem with the database since I can add new contact but I am unable to display the list. I use RecyclerView which I already created Adapter class, item layout and model for.
Adapter class - contAdapter.java
item layout - item.xml
Model - Contact
RecyclerView Layout - contactList.xml
contactList - to bind recyclerview with adapter
I wish to see the list of contact added to the database to be displayed on the screen but I have been stuck here for quite some time since I cannot figure out what the problem is :(
Here is my Contact Model:
public Contact() {
}
public Contact(String contName, String contNumber) {
this.contName = contName;
this.contNumber = contNumber;
}
public String getContName() {
return contName;
}
public void setContName(String contName) {
this.contName = contName;
}
public String getContNumber() {
return contNumber;
}
public void setContNumber(String contNumber) {
this.contNumber = contNumber;
}
contactList.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="25dp" tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/contList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
contactList.java:
package com.example.lucentproj;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;`
import java.util.ArrayList;
public class contactList extends AppCompatActivity {
RecyclerView recyclerView;
DatabaseReference reference;
contAdapter adapter;
ArrayList<Contact> list;
FirebaseUser user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_list);
user = FirebaseAuth.getInstance().getCurrentUser();
recyclerView = findViewById(R.id.contList);
reference = FirebaseDatabase.getInstance().getReference("Contact");
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
adapter = new contAdapter(this, list);
recyclerView.setAdapter(adapter);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
Contact contact = dataSnapshot.getValue(Contact.class);
list.add(contact);
}
adapter.updateList(list);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
item.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_margin="16dp"
app:cardElevation="8dp" app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:orientation="vertical"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal" />
<TextView
android:id="#+id/contname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/amaranth"
android:text="Name"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/contno"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:fontFamily="#font/amaranth_italic"
android:paddingLeft="10dp"
android:text="Number"
android:textSize="20dp"
android:textStyle="italic" />
<ImageView
android:id="#+id/cCall"
android:layout_width="38dp"
android:layout_height="30dp"
android:layout_marginLeft="280dp"
android:layout_marginTop="15dp"
android:clickable="true"
android:src="#drawable/call" />
<ImageView
android:id="#+id/cEdit"
android:layout_width="45dp"
android:layout_height="30dp"
android:layout_marginLeft="320dp"
android:layout_marginTop="15dp"
android:clickable="true"
android:src="#drawable/edit" />
</androidx.cardview.widget.CardView>
contAdapter:
package com.example.lucentproj;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class contAdapter extends RecyclerView.Adapter<contAdapter.ViewHolder> {Context context;
ArrayList<Contact> list;
public contAdapter(Context context, ArrayList<Contact> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Contact cont = list.get(position);
holder.cname.setText(cont.getContName());
holder.cnum.setText(cont.getContNumber());
}
#Override
public int getItemCount() {
return list.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView cname, cnum;
public ViewHolder(#NonNull View itemView) {
super(itemView);
cname = itemView.findViewById(R.id.contName);
cnum = itemView.findViewById(R.id.contNumber);
}
}
public void updateList(ArrayList<Contact> list){
this.list=list;
notifyDataSetChanged();
}
}
You are not updating list in Adaptor
Please add this method in your adaptor class -
public void updateList(ArrayList<Contact> list){
this.list=list;
notifyDataSetChanged();
}
And replace this line from your contactList activity to adapter.notifyDataSetChanged(); --> adapter.updateList(list);
contactList.java
package com.example.lucentproj;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;`
import java.util.ArrayList;
public class contactList extends AppCompatActivity {
RecyclerView recyclerView;
DatabaseReference reference;
contAdapter adapter;
ArrayList<Contact> list;
FirebaseUser user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_list);
user = FirebaseAuth.getInstance().getCurrentUser();
recyclerView = findViewById(R.id.contList);
reference = FirebaseDatabase.getInstance().getReference("Contact");
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
myRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Contact contact = dataSnapshot.getValue(Contact.class);
list.add(contact);
}
}
adapter = new contAdapter(this, list);
recyclerView.setAdapter(adapter);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
Contact contact = dataSnapshot.getValue(Contact.class);
list.add(contact);
}
adapter.updateList(list);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
When using a custom adapter in Firebase, I ran into a problem that everything works, but the pictures in the sheet are not displayed. Something incomprehensible is highlighted, but not her. It is necessary that they be in a normal sheet and they can be seen. I think it's because of the context in Picasso. The guide I followed had a wish(mContext) method that I can't use now. Please help, I don't understand what is the problem. I am attaching the image_item.xml code
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/text_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="20sp" />
<ImageView
android:id="#+id/image_view_upload"
android:layout_width="match_parent"
android:layout_height="200dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
activity_images
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ImagesActivity">
<ProgressBar
android:id="#+id/progress_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
private Context mContext;
private List<Upload> mUploads;
public ImageAdapter(Context context, List<Upload> uploads) {
mContext = context;
mUploads = uploads;
}
#Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.image_item, parent, false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(ImageViewHolder holder, int position) {
Upload uploadCurrent = mUploads.get(position);
holder.textViewName.setText(uploadCurrent.getName());
Picasso.get()
.load(uploadCurrent.getImageUrl())
.placeholder(R.mipmap.ic_launcher)
.fit()
.centerCrop()
.into(holder.imageView);
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName;
public ImageView imageView;
public ImageViewHolder(View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.text_view_name);
imageView = itemView.findViewById(R.id.image_view_upload);
}
}
}
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class ImagesActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private ProgressBar mProgressCircle;
private DatabaseReference mDatabaseRef;
private List<Upload> mUploads;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_images);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mProgressCircle = findViewById(R.id.progress_circle);
mUploads = new ArrayList<>();
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
mUploads.add(upload);
}
mAdapter = new ImageAdapter(ImagesActivity.this, mUploads);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
mProgressCircle.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ImagesActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
mProgressCircle.setVisibility(View.INVISIBLE);
}
});
}
}
Can anyone please help me out here???
Problem statement: I am making a chat application that is almost ready in ChatActivity. Functionality is the user can send images and text together but while sending text it's fine. The problem starts when I am sending images. And after sending when I scroll up to my all the texts start to change into the recently sent image.
ChatActivity.xml -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/bg_light"
tools:context=".ChatActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/backArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_back_arrow"
app:tint="#color/white" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profile_image"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginStart="5dp"
android:padding="5dp"
android:src="#drawable/avatar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/backArrow"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/userName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="13dp"
android:fontFamily="#font/roboto"
android:text=""
android:textColor="#color/white"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imageView7"
app:layout_constraintStart_toEndOf="#+id/profile_image"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/lastSeen"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="2dp"
android:fontFamily="#font/roboto_light"
android:text=""
android:textColor="#color/white"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imageView7"
app:layout_constraintStart_toEndOf="#+id/profile_image"
app:layout_constraintTop_toBottomOf="#+id/userName" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="-22dp" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="left"
tools:layout_editor_absoluteX="395dp" />
<ImageView
android:id="#+id/imageView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_more"
app:tint="#color/white" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/chatRecyclerView"
android:layout_width="match_parent"
android:layout_height="611dp"
android:nestedScrollingEnabled="false">
</androidx.recyclerview.widget.RecyclerView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="4dp">
<View
android:id="#+id/view14"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="#drawable/follow_active_btn"
app:layout_constraintBottom_toBottomOf="#+id/etMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/etMessage" />
<EditText
android:id="#+id/etMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="4dp"
android:background="#color/transparent"
android:ems="10"
android:hint="Message"
android:inputType="textMultiLine"
android:maxLines="4"
android:minHeight="48dp"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/sendMessageImage"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="#+id/sendMessage"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="8dp"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="#+id/etMessage"
app:layout_constraintEnd_toEndOf="#+id/view14"
app:layout_constraintTop_toTopOf="#+id/etMessage"
app:srcCompat="#drawable/comment"
app:tint="#color/purple_500" />
<ImageView
android:id="#+id/sendMessageImage"
android:layout_width="36dp"
android:layout_height="36dp"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="#+id/sendMessage"
app:layout_constraintEnd_toStartOf="#+id/sendMessage"
app:layout_constraintTop_toTopOf="#+id/sendMessage"
app:srcCompat="#drawable/clip"
app:tint="#color/black" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
ChatAdapter.java -
package com.codinggeekers.lmsbeta.Adapter;
import android.content.Context;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.codinggeekers.lmsbeta.Models.MessageModel;
import com.codinggeekers.lmsbeta.R;
import com.google.firebase.auth.FirebaseAuth;
import com.squareup.picasso.Picasso;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
public class ChatAdapter extends RecyclerView.Adapter {
ArrayList<MessageModel> list;
Context context;
int SENDER_VIEW_TYPE = 1;
int RECEIVER_VIEW_TYPE = 2;
public ChatAdapter(ArrayList<MessageModel> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public long getItemId(int position) {
return position;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == SENDER_VIEW_TYPE) {
View view = LayoutInflater.from(context).inflate(R.layout.sample_sender, parent, false);
return new SenderViewHolder(view);
}
else {
View view = LayoutInflater.from(context).inflate(R.layout.sample_receiver, parent, false);
return new ReceiverViewHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
MessageModel message = list.get(position);
Timestamp ts = new Timestamp(message.getTimestamp());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm a");
String time = simpleDateFormat.format(ts.getTime());
RequestOptions requestOptions = new RequestOptions();
requestOptions = requestOptions.transforms(new CenterCrop(), new RoundedCorners(10));
if(holder.getClass() == SenderViewHolder.class) {
if (message.getMsgImg()!=null) {
((SenderViewHolder)holder).senderImageLayout.setVisibility(View.VISIBLE);
((SenderViewHolder)holder).senderTextLayout.setVisibility(View.GONE);
// Picasso.get().load(message.getMsgImg()).placeholder(R.drawable.placeholder).into(((SenderViewHolder)holder).senderImage);
Glide.with(((SenderViewHolder)holder).itemView.getContext()).load(message.getMsgImg()).apply(requestOptions)
.placeholder(R.drawable.placeholder).into(((SenderViewHolder)holder).senderImage);
} else {
((SenderViewHolder)holder).senderMsg.setText(message.getMessage());
((SenderViewHolder)holder).senderTime.setText(time);
}
}
else {
if (message.getMsgImg()!=null) {
((ReceiverViewHolder)holder).receiverImageLayout.setVisibility(View.VISIBLE);
// Picasso.get().load(message.getMsgImg()).placeholder(R.drawable.placeholder).into(((ReceiverViewHolder)holder).receiverImage);
Glide.with(((ReceiverViewHolder)holder).itemView.getContext()).load(message.getMsgImg()).apply(requestOptions)
.placeholder(R.drawable.placeholder).into(((ReceiverViewHolder)holder).receiverImage);
} else {
((ReceiverViewHolder)holder).receiverMsg.setText(message.getMessage());
((ReceiverViewHolder)holder).receiverTime.setText(time);
}
}
}
#Override
public int getItemViewType(int position) {
if(list.get(position).getuId().equals(FirebaseAuth.getInstance().getUid())) {
return SENDER_VIEW_TYPE;
}
else {
return RECEIVER_VIEW_TYPE;
}
}
#Override
public int getItemCount() {
return list.size();
}
public class ReceiverViewHolder extends RecyclerView.ViewHolder {
TextView receiverMsg, receiverTime;
ImageView receiverImage;
ConstraintLayout receiverImageLayout;
public ReceiverViewHolder(#NonNull View itemView) {
super(itemView);
receiverMsg = itemView.findViewById(R.id.receiverText);
receiverTime = itemView.findViewById(R.id.receiverTime);
receiverImage = itemView.findViewById(R.id.receiverImage);
receiverImageLayout = itemView.findViewById(R.id.imageConstraintLayoutReceiver);
}
}
public class SenderViewHolder extends RecyclerView.ViewHolder {
TextView senderMsg, senderTime;
ImageView senderImage;
ConstraintLayout senderImageLayout;
ConstraintLayout senderTextLayout;
public SenderViewHolder(#NonNull View itemView) {
super(itemView);
senderMsg = itemView.findViewById(R.id.senderText);
senderTime = itemView.findViewById(R.id.senderTime);
senderImage = itemView.findViewById(R.id.senderImage);
senderImageLayout = itemView.findViewById(R.id.imageConstraintLayoutSender);
senderTextLayout = itemView.findViewById(R.id.textConstraintLayoutSender);
}
}
}
ChatActivity.java -
package com.codinggeekers.lmsbeta;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import com.codinggeekers.lmsbeta.Adapter.ChatAdapter;
import com.codinggeekers.lmsbeta.Models.MessageModel;
import com.codinggeekers.lmsbeta.databinding.ActivityChatBinding;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.Date;
public class ChatActivity extends AppCompatActivity {
ActivityChatBinding binding;
ProgressDialog dialog;
FirebaseAuth auth;
FirebaseDatabase database;
FirebaseStorage storage;
ActivityResultLauncher<String> galleryLauncher;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityChatBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
auth = FirebaseAuth.getInstance();
database = FirebaseDatabase.getInstance();
storage = FirebaseStorage.getInstance();
dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setTitle("Sending Image...");
dialog.setMessage("Please wait...");
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
// Sender and Receiver Ids
final String senderId = auth.getUid();
String receiveId = getIntent().getStringExtra("userId");
String userName = getIntent().getStringExtra("userName");
String profilePic = getIntent().getStringExtra("profilePic");
binding.userName.setText(userName);
Picasso.get().load(profilePic).placeholder(R.drawable.avatar).into(binding.profileImage);
binding.backArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ChatActivity.this, UsersChatActivity.class);
startActivity(intent);
}
});
final ArrayList<MessageModel> messageModels = new ArrayList<MessageModel>();
final ChatAdapter chatAdapter = new ChatAdapter(messageModels, this);
binding.chatRecyclerView.setAdapter(chatAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
binding.chatRecyclerView.setHasFixedSize(true);
binding.chatRecyclerView.setLayoutManager(layoutManager);
final String senderRoom = senderId + receiveId;
final String receiverRoom = receiveId + senderId;
database.getReference().child("Chats")
.child(senderRoom)
.addValueEventListener(new ValueEventListener() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
messageModels.clear();
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
MessageModel model = snapshot1.getValue(MessageModel.class);
messageModels.add(model);
}
chatAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
binding.sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String message = binding.etMessage.getText().toString();
if (message.matches("")) {
} else {
final MessageModel model = new MessageModel(senderId, message, "text");
model.setTimestamp(new Date().getTime());
binding.etMessage.setText("");
database.getReference().child("Chats")
.child(senderRoom)
.push()
.setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(#NonNull Void unused) {
database.getReference().child("Chats").child(receiverRoom).push().setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(#NonNull Void unused) {
}
});
}
});
}
}
});
binding.sendMessageImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
galleryLauncher.launch("image/*");
}
});
galleryLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(Uri result) {
dialog.show();
final StorageReference reference = storage.getReference().child("chats")
.child(senderRoom).child(new Date().getTime() + "");
reference.putFile(result).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
final MessageModel model = new MessageModel(senderId, new Date().getTime(), uri.toString(), "image");
database.getReference()
.child("Chats")
.child(senderRoom)
.push()
.setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
database.getReference().child("Chats").child(receiverRoom).push().setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
dialog.dismiss();
binding.sendMessageImage.setImageURI(Uri.EMPTY);
Intent intent = getIntent();
finish();
startActivity(intent);
}
});
}
});
}
});
}
});
}
});
binding.userName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ChatActivity.this, FriendsProfileActivity.class);
intent.putExtra("userName", userName);
intent.putExtra("userId", receiveId);
intent.putExtra("profilePic", profilePic);
startActivity(intent);
}
});
}
}
ItemViewType should start at 0.
Try to change them to this:
int SENDER_VIEW_TYPE = 0;
int RECEIVER_VIEW_TYPE = 1;
I have a screen that shows my movie names and their pictures which are in my Firebase. It shows them with the pictures.
My database's structure is like this. name is the string which is the name of my movie. profilePic is the string that contains the picture link from Firebase storage.
What I want is, when I click on any picture which are listed, I want to display it on another activity with bigger size (like opening someone's WhatsApp or Facebook profile picture)
These are my classes that works perfectly. How can I do this?
Movies.java
package com.example.XXXX;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class Movies extends AppCompatActivity {
DatabaseReference reference;
RecyclerView recyclerView;
ArrayList<Profile> list;
MyAdapter adapter;
private String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movies);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview_films);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
reference = FirebaseDatabase.getInstance().getReference().child("Films");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
list = new ArrayList<Profile>();
for(DataSnapshot dataSnapshot1: dataSnapshot.getChildren()){
Profile p = dataSnapshot1.getValue(Profile.class);
list.add(p);
}
adapter = new MyAdapter(Movies.this,list);
recyclerView.setAdapter(adapter);
findViewById(R.id.loadingPanel).setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(Movies.this,"Ooops... Something is wrong.",Toast.LENGTH_SHORT).show();
}
});
Intent intent = getIntent();
message = intent.getStringExtra("EXTRA_MESSAGE");
ImageButton backButton = (ImageButton) findViewById(R.id.imageButton13);
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(Movies.this, Menu.class);
i.putExtra("EXTRA_MESSAGE",message);
startActivity(i);
overridePendingTransition(R.anim.slide_in_left,R.anim.slide_out_right);
}
});
}
#Override
public void onBackPressed() {
Intent i = new Intent(Movies.this, Menu.class);
i.putExtra("EXTRA_MESSAGE",message);
startActivity(i);
overridePendingTransition(R.anim.slide_in_left,R.anim.slide_out_right);
}
}
MyAdapter.java
package com.example.XXXX;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context context;
ArrayList<Profile> profiles;
public MyAdapter(Context c, ArrayList<Profile> p){
context = c;
profiles = p;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.cardview,viewGroup, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.name.setText(profiles.get(i).getName());
Picasso.get().load(profiles.get(i).getProfilePic()).into(myViewHolder.profilePic);
}
#Override
public int getItemCount() {
return profiles.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView name;
ImageView profilePic;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.film_name);
profilePic = (ImageView) itemView.findViewById(R.id.filmProfile);
}
}
}
Profile.java
package com.example.XXXX;
public class Profile {
private String name;
private String profilePic;
public Profile() {
}
public Profile(String name, String profilePic) {
this.name = name;
this.profilePic = profilePic;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProfilePic() {
return profilePic;
}
public void setProfilePic(String profilePic) {
this.profilePic = profilePic;
}
}
activity_movies.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Movies"
android:background="#drawable/background">
<include
android:id="#+id/toolbar_movies"
layout="#layout/toolbar_movies" />
<RelativeLayout
android:id="#+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="88dp"
android:layout_marginBottom="10dp">
<LinearLayout
android:id="#+id/layoutoffilms"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_films"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</ScrollView>
</LinearLayout>
cardview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#drawable/border"
android:layout_marginTop="10dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="#+id/filmProfile"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/film_name"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:layout_gravity="center_vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.08"
android:textSize="20sp"/>
</LinearLayout>
</LinearLayout>
Modify view holder with view as
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView name;
ImageView profilePic;
View mView;
public MyViewHolder(#NonNull View itemView)
{
super(itemView);
mView = itemView;
name = (TextView) itemView.findViewById(R.id.film_name);
profilePic = (ImageView) itemView.findViewById(R.id.filmProfile);
}
}
Implement on click listener of view holder in adapter, then start the activity with image url.
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.name.setText(profiles.get(i).getName());
Picasso.get().load(profiles.get(i).getProfilePic()).into(myViewHolder.profilePic);
mViewHolder.mView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
startImageActivity(profiles.get(i).getProfilePic());
}
});
}
3.Create activity and start with image view of required dimension.
void startImageActivity(String imgUrl)
{
Intent intent = new Intent(context,ViewImage.class);
intent.putExtra("profilePic",imgUrl);
context.startActivity(intent);
}
Or to open image in an external application try
void startImageActivity(String imgUrl)
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(imgUrl));
context.startActivity(intent);
}
Resize your bitmap:
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
originalBitmap, newWidth, newHeight, false);
You can use this library for the zoom in and zoom out functionality like this is the link Zoom library
You need to add this gradle in your project
implementation 'com.otaliastudios:zoomlayout:1.6.1'
Check this example layout below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/dark_grey"
android:orientation="vertical"
android:weightSum="13">
<ImageView
android:id="#+id/iv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_margin="#dimen/margin_small"
android:padding="#dimen/margin_small"
android:src="#drawable/ic_skip" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="6" />
<com.otaliastudios.zoom.ZoomImageView
android:id="#+id/zoom_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:scrollbars="vertical|horizontal"
app:alignment="center"
app:animationDuration="280"
app:flingEnabled="true"
app:horizontalPanEnabled="true"
app:maxZoom="2.5"
app:maxZoomType="zoom"
app:minZoom="0.7"
app:minZoomType="zoom"
app:overPinchable="true"
app:overScrollHorizontal="true"
app:overScrollVertical="true"
app:transformation="centerInside"
app:transformationGravity="auto"
app:verticalPanEnabled="true"
app:zoomEnabled="true" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="5" />
</LinearLayout>
And in the JAVA class you need to load the image like below, I am using the Glide for the image loading like below
GlideApp.with(this)
.asBitmap()
.load(YOUR_IMAGE_URL)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
YOUR_IMAGEVIEW.setImageBitmap(resource);
}
});
Check the ZoomActivity.java for the demo purpose like below
public class ZoomActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_zoom);
// ActivityZoomBinding mBinding = DataBindingUtil.setContentView(this, R.layout.activity_zoom);
ImageView zoomImage = findViewById(R.id.zoom_image);
///GETTING INTENT DATA
Intent intent = getIntent();
if (intent.hasExtra("ZOOM_IMAGE")) {
String imageUrl = intent.getStringExtra("ZOOM_IMAGE");
GlideApp.with(this)
.asBitmap()
.load(imageUrl)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
zoomImage.setImageBitmap(resource);
}
});
}
}
}
I have an app with a bottom navigation view that changes between 4 fragments and I'm trying to make it so that those fragments are displayed with data from firebase using FirebaseRecyclerView Adapter.
I have everything set up but the layout that the FirebaseRecyclerView Adapter inflates is not appearing.
My MainAcitivity.java
package com.pap.diogo.pilltrack;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.firebase.ui.database.SnapshotParser;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
public class MainActivity extends AppCompatActivity {
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.navigation_home:
selectedFragment = new HomeFragment();
break;
case R.id.navigation_pills:
selectedFragment = new PillsFragment();
break;
case R.id.navigation_appointment:
selectedFragment = new AppointsFragment();
break;
case R.id.navigation_account:
selectedFragment = new AccountFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();
return true;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null) {
Intent VerifyLogin = new Intent(MainActivity.this, Launcher.class);
VerifyLogin.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(VerifyLogin);
}
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
}
};
My AccountFragment.java
package com.pap.diogo.pilltrack;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.firebase.ui.database.SnapshotParser;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
public class AccountFragment extends Fragment {
private RecyclerView AccountUsers;
private View mMainView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mMainView = inflater.inflate(R.layout.fragment_account, container, false);
AccountUsers = mMainView.findViewById(R.id.accountlist);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
AccountUsers.setLayoutManager(linearLayoutManager);
AccountUsers.setHasFixedSize(true);
return mMainView;
}
#Override
public void onStart() {
super.onStart();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
final String userid = user.getUid();
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
FirebaseRecyclerOptions<Account> AccountQ = new FirebaseRecyclerOptions.Builder<Account>().setQuery(ref, Account.class).setLifecycleOwner(this).build();
FirebaseRecyclerAdapter<Account, AccountInfo> AccountAdapter = new FirebaseRecyclerAdapter<Account, AccountInfo>(AccountQ){
#NonNull
#Override
public AccountInfo onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new AccountInfo(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.account, viewGroup, false));
}
#Override
protected void onBindViewHolder(#NonNull final AccountInfo holder, int position, #NonNull final Account model) {
ref.child(userid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final String name = dataSnapshot.child("name").getValue().toString();
final String age = dataSnapshot.child("idade").getValue().toString();
holder.setName(name);
holder.setAge(age);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
};
AccountUsers.setAdapter(AccountAdapter);
}
public static class AccountInfo extends RecyclerView.ViewHolder{
View AccountL;
public AccountInfo(#NonNull View itemView) {
super(itemView);
AccountL = itemView;
}
public void setName(String name){
TextView AccountName = AccountL.findViewById(R.id.AccountName0);
AccountName.setText(name);
}
public void setAge(String age){
TextView AccountAge = AccountL.findViewById(R.id.AccountAge0);
AccountAge.setText(age);
}
}
}
My account.xml
<?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="match_parent">
<RelativeLayout
android:id="#+id/AccountUser"
android:layout_width="match_parent"
android:layout_height="163dp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp"
android:background="#drawable/edit_bg"
android:padding="15dp">
<RelativeLayout
android:id="#+id/AccountImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/AccountInfos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/AccountImage"
android:layout_toEndOf="#id/AccountImage"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp">
<TextView
android:id="#+id/AccountName0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Nome1"
android:textColor="#color/colorWhite"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/AccountAge0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountName0"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Idade1"
android:textColor="#color/colorWhite"
android:textSize="20sp"
android:textStyle="bold" />
<Button
android:id="#+id/AccountChangePass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountAge0"
android:text="Mudar Palavra-Passe"
android:textColor="#color/colorWhite"
android:textSize="18sp"
android:textStyle="bold"
android:textAllCaps="false"
android:padding="10dp"
android:layout_marginTop="10dp"
android:background="#drawable/custom_button"/>
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountUser">
<ImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:src="#drawable/ic_add"
android:padding="5dp"
android:background="#drawable/add_button"/>
</RelativeLayout>
</RelativeLayout>
My fragment_account.xml
<?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="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/accountlist">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
GitHub of my APP
I fixed it.
All I had to do was to remove this line of code:
AccountUsers.setHasFixedSize(true);