I was trying to make a chat app for the android, so I used RecyclerView for it. I have a problem for the adapter, my chat room's displaying blank for the JSON response they get. Did I miss something on my code?
Here is my adapter class
public class PesanRecycleAdapter extends RecyclerView.Adapter<PesanRecycleAdapter.ViewHolder> {
private String username;
private Context context;
private int SELF = 786;
private ArrayList<Pesan> pesan;
public PesanRecycleAdapter(Context context, ArrayList<Pesan> pesan, String username){
this.username = username;
this.pesan = pesan;
this.context = context;
}
#Override
public int getItemViewType(int position) {
Pesan psn = pesan.get(position);
if (psn.getUsernameFrom() == username) {
return SELF;
}
return position;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
if (viewType == SELF) {
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_thread_me, parent, false);
} else {
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_thread_other, parent, false);
}
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Pesan psn = pesan.get(position);
holder.textViewMessage.setText(psn.getPesan());
holder.textViewTime.setText(psn.getSentAt());
}
#Override
public int getItemCount() {
return pesan.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewMessage;
public TextView textViewTime;
public ViewHolder(View itemView) {
super(itemView);
textViewMessage = (TextView) itemView.findViewById(R.id.textViewMessage);
textViewTime = (TextView) itemView.findViewById(R.id.textViewTime);
}
}
}
Any help or suggestion is welcome
And here where I used that adapter on activity
public void getpesan() {
try {
apiservice.get_pesan(username, "ahnafgg").enqueue(new Callback<ResponPesan>() {
#Override
public void onResponse(Call<ResponPesan> call, Response<ResponPesan> response) {
Log.d(TAG, "onResponse: response..."+response);
dummyData = response.body().getPesan();
createRecycleView();
}
#Override
public void onFailure(Call<ResponPesan> call, Throwable t) {
Log.d(TAG, "onFailure: response...");
Toast.makeText(RuangPesan.this,"Gagal ambil chat",Toast.LENGTH_SHORT).show();
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void createRecycleView(){
adapter = new PesanRecycleAdapter(RuangPesan.this, pesan, username);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Log.d(TAG, "********************************");
scrollToBottom();
}
Probably you forgot to set date in the model before initialising recycler view
Use the following way from your activity class:
initData(); //Do this first
RecyclerView recyclerView = findViewById(R.id.recyclerview);
Context context = MainActivity.this;
PesanRecycleAdapter pesanRecycleAdapter = new PesanRecycleAdapter(context, list,"Fahad");
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(pesanRecycleAdapter);
I think everything is okay here, maybe you forgot setting layoutManager for recyclerView or notify adapter after setting data
Related
I am doing a vaccine name list which shows the list of vaccine names from a table in a database. Once run, the RecyclerView was multiplied to the correct array size which is 6 but the names were not showing and null.
These are my block of codes for that particular list view
AboutVaccines.java
private void viewJsonData() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
myApi = retrofit.create(MyAPI.class);
Call<ArrayList<VaccineModel>> modelarraylist = myApi.callArrayList();
modelarraylist.enqueue(new Callback<ArrayList<VaccineModel>>() {
#Override
public void onResponse(Call<ArrayList<VaccineModel>> call, retrofit2.Response<ArrayList<VaccineModel>> response) {
modelArrayList = response.body();
int i = 0;
for(i = 0; i < modelArrayList.size(); i++){
vaccineAdapter = new VaccineAdapter(modelArrayList, AboutVaccines.this);
LinearLayoutManager manager = new LinearLayoutManager(AboutVaccines.this,
RecyclerView.VERTICAL, false);
vaccinerecycler.setLayoutManager(manager);
vaccinerecycler.setAdapter(vaccineAdapter);
}
}
#Override
public void onFailure(Call<ArrayList<VaccineModel>> call, Throwable t) {
Toast.makeText(AboutVaccines.this, "data was not fetched!", Toast.LENGTH_SHORT).show();
}
});
}
VaccineAdapter.java
public class VaccineAdapter extends RecyclerView.Adapter<VaccineAdapter.ViewHolder> {
private ArrayList<VaccineModel> modelArrayList;
private Context context;
public VaccineAdapter(ArrayList<VaccineModel> modelArrayList, Context context) {
this.modelArrayList = modelArrayList;
this.context = context;
}
#NonNull
#Override
public VaccineAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.abtvaccinesrecyclerview, parent, false);
return new VaccineAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull VaccineAdapter.ViewHolder holder, int position) {
holder.vname.setText(modelArrayList.get(position).getVaccineName());
}
#Override
public int getItemCount() {
return modelArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView vname;
public ViewHolder(#NonNull View itemView) {
super(itemView);
vname = itemView.findViewById(R.id.vaccinename);
}
}
}
MyAPI.java
public interface MyAPI {
#GET("vaccinedata.php")
Call<ArrayList<VaccineModel>> callArrayList();
}
RecyclerView shows 6 layouts but the vaccine names is still not shown
The logcat also shows error "No adapter attached; skipping layout" for the RecyclerView
I am trying to fetch data from my Parse database and display it into my RecyclerView. Upon entering the Fragment, the RecyclerView displays no data. It isn't until I Swipe Refresh the feed that the items are accurately displayed in the RecyclerView. How can I make the RecyclerView have the items already initialized upon entering the Fragment?
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
placeName = view.findViewById(R.id.profileEstablishmentName);
placeAddress = view.findViewById(R.id.restroomAddressInfo);
placeRating = view.findViewById(R.id.ratingBar);
rvFeed = view.findViewById(R.id.rvRestaurant);
swipeContainer = view.findViewById(R.id.swipeContainer);
swipeContainer.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() { queryPosts(); }
});
allPosts = new ArrayList<>();
adapter = new PostsAdapter(getContext(), allPosts);
rvFeed.setAdapter(adapter);
rvFeed.setLayoutManager(new LinearLayoutManager(getContext()));
queryPosts();
setHasOptionsMenu(true);
}
Parse Query:
protected void queryPosts(){
ParseQuery<Post> query = ParseQuery.getQuery(Post.class);
query.include(Post.KEY_USER);
query.include(Post.KEY_PLACE_NAME);
//Constraint to only see posts of the selected Restaurant
query.whereEqualTo(Post.KEY_PLACE_NAME, placeName.getText().toString());
query.setLimit(20);
//Filters the order of the posts based on the time created key (newest on top)
query.addDescendingOrder(Post.KEY_CREATED_KEY);
query.findInBackground(new FindCallback<Post>() {
#Override
public void done(List<Post> posts, ParseException e) {
if (e != null) {
Log.e(TAG, "Issue with getting posts", e);
return;
}
for(Post post : posts){
Log.i(TAG, "Post: " + post.getPlaceName());
}
adapter.clear();
allPosts.addAll(posts);
adapter.notifyDataSetChanged();
swipeContainer.setRefreshing(false);
}
});
}
PostAdapter:
public class PostsAdapter extends RecyclerView.Adapter<PostsAdapter.ViewHolder>{
private Context context;
private List<Post> posts;
public PostsAdapter(Context context, List<Post> posts){
this.context = context;
this.posts = posts;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_post, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Post post = posts.get(position);
holder.bind(post);
}
#Override
public int getItemCount() {
return posts.size();
}
public void clear() {
posts.clear();
notifyDataSetChanged();
}
// Add a list of items -- change to type used
public void addAll(List<Post> list) {
posts.addAll(list);
notifyDataSetChanged();
}
class ViewHolder extends RecyclerView.ViewHolder{
private TextView tvUsername;
private TextView tvDescription;
private TextView tvPlaceName;
private ImageView ivImage;
public ViewHolder(#NonNull View itemView) {
super(itemView);
tvUsername = itemView.findViewById(R.id.username);
tvPlaceName = itemView.findViewById(R.id.placeName);
tvDescription = itemView.findViewById(R.id.reviewDescription);
ivImage = itemView.findViewById(R.id.ivImage);
}
public void bind(Post post) {
//Bind the post data to the view elements
tvDescription.setText(post.getDescription());
tvUsername.setText("#" + post.getUser().getUsername());
tvPlaceName.setText(post.getPlaceName());
ParseFile image = post.getImage();
if (image != null) {
Glide.with(context).load(post.getImage().getUrl()).into(ivImage);
}
}
}
I have an adapter class Where i Want to show a BLOCK USER dialog on particular position.
for example if i want to block position 1 of recyclerView .
So can any one help me porgrammatically?
Given below is the Code Of adapter Please check
I want to block user profile based on Recycler View position
if someone could help me in it please;
public class TableProfileAdapter extends RecyclerView.Adapter<TableProfileAdapter.MyViewHolder> {
Context context;
Activity getActivity;
List<TableProfile> profileUser;
OnRecItemClick onRecItemClick;
private boolean isScaleAnimationDone = false;
private boolean isTimerTextViewActionUpCalled = false;
public TableProfileAdapter(List<TableProfile> profileUser, Context context) {
this.profileUser = profileUser;
this.context = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.profile_item, parent, false);
return new MyViewHolder(view, onRecItemClick);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
TableProfile data = profileUser.get(position);
holder.tvUserName.setText(data.getProfileName());
Bitmap image = BitmapManager.byteToBitmap(data.getProfileImage());
holder.profilePic.setImageBitmap(image);
if (context instanceof AccessProfileManagementActivity) {
context.startActivity(new Intent(context,HomeActivity.class));
} else if (context instanceof ProfileManagement) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, ProfileDetailsActivity.class);
TableProfile model = profileUser.get(holder.getAdapterPosition());
intent.putExtra("DATA", model);
context.startActivity(intent);
notifyDataSetChanged();
((Activity) context).finish();
}
});
}
}
#Override
public int getItemCount() {
return profileUser.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CircleImageView profilePic;
TextView tvUserName, birthday;
OnRecItemClick onRecItemClick;
RelativeLayout relativeLayout;
public MyViewHolder(#NonNull View itemView, OnRecItemClick onRecItemClick) {
super(itemView);
profilePic = itemView.findViewById(R.id.profileImage);
tvUserName = itemView.findViewById(R.id.userName);
relativeLayout = itemView.findViewById(R.id.relTop);
this.onRecItemClick = onRecItemClick;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
onRecItemClick.onItemClick(getAdapterPosition());
}
}
public interface OnRecItemClick {
void onItemClick(int position);
}
}
here is my code i dont know why its not working now songs is a simple java class which contains getter setters
Before fetching data from JSON i try to statically add data in recycleView and that was working perfectly fine.
Here is code,
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_track, container, false);
myOnClickListener = new track.MyOnClickListener(getActivity());
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview1);
//recyclerView.setHasFixedSize(true);
layoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
loadData();
return view;
}
code of JSON parsing using volley
private void loadData()
{
String url = "http://homejobs.live/mydata.php";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>(){
#Override
public void onResponse(String response) {
try{
JSONArray jsonArray = new JSONArray(response);
Log.d("test", String.valueOf(jsonArray));
Log.d("test", String.valueOf(jsonArray.length()));
for(int i =0 ; i < jsonArray.length() ; i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
songs item = new songs(
jsonObject.getString("id"),
jsonObject.getString("name"),
jsonObject.getString("uri")
);
Log.d("key", String.valueOf(item));
data.add(item);
}
adapter = new recycler_view_adapter(data);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("error"+error);
}
}
);
mRequestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
mRequestQueue.add(stringRequest);
}
recycler_view_adapter class
public class recycler_view_adapter extends RecyclerView.Adapter<recycler_view_adapter.MyViewHolder> {
private ArrayList<songs> dataSet;
public static class MyViewHolder extends RecyclerView.ViewHolder {
public static TextView textViewName;
public static ImageView imageViewIcon;
public MyViewHolder(View itemView) {
super(itemView);
this.textViewName = (TextView) itemView.findViewById(R.id.textView);
this.imageViewIcon = (ImageView) itemView.findViewById(R.id.imageView3);
}
}
public recycler_view_adapter(ArrayList<songs> data) {
this.dataSet = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card, parent, false);
view.setOnClickListener(track.myOnClickListener);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Log.d("hy","test");
songs songsData = dataSet.get(position);
MyViewHolder.textViewName.setText(songsData.getName());
System.out.println("hello"+position);
Picasso.get()
.load(songsData.getImage())
.into(MyViewHolder.imageViewIcon);
}
#Override
public int getItemCount()
{
return dataSet.size();
}
}
In your onBindViewHolder, change the following code
MyViewHolder.textViewName.setText(songsData.getName());
System.out.println("hello"+position);
Picasso.get()
.load(songsData.getImage())
.into(MyViewHolder.imageViewIcon);
to the following
holder.textViewName.setText(songsData.getName());
System.out.println("hello"+position);
Picasso.get()
.load(songsData.getImage())
.into(holder.imageViewIcon);
In your code, you are trying to access the textview by using the class name. Instead you should use the holder variable.
Also please check whether you are parsing the json correctly. Check if the
data.add(item);
in the api response is getting executed.
Another suggestion would be to check the size of your dataSet array in the adapter constructor.
Try replacing onBindViewHolder with this
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Log.d("hy","test");
songs songsData = dataSet.get(position);
holder.textViewName.setText(songsData.getName());
System.out.println("hello"+position);
Picasso.get()
.load(songsData.getImage())
.into(holder.imageViewIcon);
}
I've implementend a RecyclerView as follow
The Adapter with the Holder
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.indovinelloelement,parent,false);
MyHolder holder = new MyHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
holder.category.setText(data.get(position).getCategory());
holder.difficulty.setText(""+data.get(position).getDifficulty());
holder.title.setText(data.get(position).getTitle());
holder.score.setText(""+data.get(position).getScore());
if(data.get(position).isLocked())
holder.setLocked();
else
holder.setUnlocked();
}
public DataGestour.Indovinello getIndovinello(int pos){
return data.get(pos);
}
#Override
public int getItemCount() {
return data.size();
}
public class MyHolder extends RecyclerView.ViewHolder {
public TextView category,score,difficulty,title;
private ImageView lock_state;
public MyHolder(View itemView) {
super(itemView);
category = (TextView)itemView.findViewById(R.id.categoria);
score = (TextView)itemView.findViewById(R.id.punteggio);
difficulty = (TextView) itemView.findViewById(R.id.difficolta);
title = (TextView)itemView.findViewById(R.id.titolo);
lock_state = (ImageView) itemView.findViewById(R.id.lock_state);
}
public void setLocked(){
lock_state.setImageResource(R.drawable.ic_lock_outline_black_24dp);
}
public void setUnlocked(){
lock_state.setImageResource(R.drawable.ic_lock_open_black_24dp);
}
}
ArrayList<DataGestour.Indovinello> data;
Context context;
public MyAdapter(Context context, ArrayList<DataGestour.Indovinello> list){
this.context = context;
this.data = list;
}
}
and the RecyclerView:
rc = (RecyclerView)root_view.findViewById(R.id.lista_domande);
rc.setHasFixedSize(true);
LinearLayoutManager ly = new LinearLayoutManager(getContext());
ly.setOrientation(LinearLayoutManager.VERTICAL);
rc.setLayoutManager(ly);
try{
gestour = new DataGestour(getContext());
}catch (IllegalStateException e){
Log.e("DataManager",e.getMessage());
};
adapter = new MyAdapter(getContext(),gestour.getAllDatas());
rc.setAdapter(adapter);
adapter.notifyDataSetChanged();
where DataGestoure is a class that manipulates some data from a
database and store them in a ArrayList (DataGestour.getAllDatas is the method to return the data under a ArrayList)
The problem start only if the ArrayList contains more then 3 items becouse the RecyclerView doen't show them despite the fact that the adapter holds all the data in ArrayList< DataGestour.Indovinello > data
Well, you need a little more order in your code, since it is not properly structured, by default the RecyclerView has its Scrolleable view unless in the XML this attribute is removed, well I recommend that you use this code in your adapter and use a model to save the information you get from your BD, that is the correct way to work to keep everything in order and it is easier to work it, once this is done you can use this code perfectly that I am sure will work, remember to only pass information to my Model that in my case calls it "Model" and with this the error of your data load will be solved. It is also advisable to use a List <> for these cases since the Arrays <> tend to have errors when you manipulate the data and more if you do it the way you present the code.
private List<Model> mDataList;
public MyAdapter(Context context){
this.context = context;
this.mDataList = new ArrayList<>();
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.indovinelloelement,parent,false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
MyHolder holder = (MyHolder) MyHolder;
hoder.bind(mDataList.getPosition(position));
}
#Override
public int getItemCount() {
return mDataList.size();
}
public void setData(List<Model> list) {
mDataList.clear();
mDataList.addAll(list);
notifyDataSetChanged();
}
public class MyHolder extends RecyclerView.ViewHolder {
TextView category;
category = (TextView)itemView.findViewById(R.id.categoria);
TextView score;
score = (TextView)itemView.findViewById(R.id.punteggio);
TextView difficulty;
difficulty = (TextView) itemView.findViewById(R.id.difficolta);
TextView title;
title = (TextView)itemView.findViewById(R.id.titolo);
ImageView lock_state;
lock_state = (ImageView) itemView.findViewById(R.id.lock_state);
public MyHolder(View itemView) {
super(itemView);
}
protected void bind(Model model){
category.setText(model.getCategory());
score.setText(model.getScore());
difficulty.setText(model.getDifficulty());
title.setText(model.getTitle());
if(model.isLocked()){
lock_state.setImageResource(R.drawable.ic_lock_outline_black_24dp);
} else {
lock_state.setImageResource(R.drawable.ic_lock_open_black_24dp);
}
}
}
}
And for your class that contains the RecyclerView use the code as follows.
RecyclerView mRecyclerView;
mRecyclerView = (RecyclerView)root_view.findViewById(R.id.lista_domande);
private MyAdapter mAdapter;
private List<Model> mDataList;
private DataGestour gestour;
private void setupRecyclerView(){
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
mAdapter = new MyAdapter(getContext());
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setData(mDataList);
}
private void getDataDB(){
mDataList.add(gestour.getAllDatas);
}