How to show images using recycle view and picasso in android/ java? - java

I am having trouble showing images that I collected from a website into a recycle view. I first got the image urls using jsoup. Then I added the urls in a list called imgURLS. Now I want to show those images in gridview that has recycle view. The code I have no errors but the images are not showen when I run my android project. Its just blank. Here is some of my code
MAINACTIVITY.JAVA
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new URLcollector().execute();
imageView = findViewById(R.id.imageView);
//setBKG = findViewById(R.id.setBKG);
rvMain = findViewById(R.id.rvMain);
// can add another parameter here like text
MyAdapter adapter = new MyAdapter(imgURLS);
rvMain.setLayoutManager(new GridLayoutManager(MainActivity.this, 2));
rvMain.setAdapter(adapter);
}
then still in mainactivity.java
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
// String[] companyList;
List<String> logoList;
ImageView currentView;
Bitmap imgBitmaps;
public MyAdapter( List<String> logoList) {
// this.companyList = companyList;
this.logoList = logoList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
MyViewHolder viewHolder = new MyViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// load image from picasso and then
Context context = holder.logo.getContext(); //<----- Add this line
Picasso.with(context).load(imgURLS.get(position)).into(holder.logo);
}
#Override
public int getItemCount() {
return logoList.size();
}
}
My questions are
1) Am I using Picasso correctly?
2) Why did I not be able to see the images(keep in mind visible is on in xml)?
Let me know if I need to provide more of my code.

#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
// load image from picasso and then pass it to set Image
Picasso.with(MainActivity.this)
.load(logoList.get(position))
.placeholder(R.mipmap.ic_launcher) // optional
.error(R.mipmap.ic_launcher) //if error
.into(holder.logo);
holder.logo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "This is: " , Toast.LENGTH_SHORT).show();
}
});
// holder.name.setText(companyList[position]);
}
If your url is correct. try something like this and don't forget to set INTERNT permission in Manifest.
<uses-permission android:name="android.permission.INTERNET"/>

Related

How to Imageview hide when url is empty

I have a Imageview its load image from Firebase Database url with Picasso Image loader. I wish to hide imageview when firebase database url is empty. How to set Imageview setVisibility gone in that time.
My code is
LoadData(categoryId);
}
private void LoadData(String categoryId) {
options = new FirebaseRecyclerOptions.Builder<TrollModel>().setQuery(MCC,TrollModel.class).build();
adapter = new FirebaseRecyclerAdapter<TrollModel, TrollViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull TrollViewHolder trollViewHolder, int i, #NonNull TrollModel trollModel) {
trollViewHolder.thrillername.setText(trollModel.getTitle());
Picasso.get().load(trollModel.getImage())
.into(trollViewHolder.thrillersimage);
trollViewHolder.setItemClickListner(new ItemClickListner() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent detailsIntent = new Intent(TrollActivity.this, TrollDetailActivity.class);
detailsIntent.putExtra("CategoryId", adapter.getRef(position).getKey());
startActivity(detailsIntent);
}
});
}
#NonNull
#Override
public TrollViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.troll_items, parent, false);
return new TrollViewHolder(v);
}
};
adapter.startListening();
recyclerView.setAdapter(adapter);
}
}
There is setVisibility() funciton for every View in android. You can find this if you google it in right way.
Refer below code to solve your problem.
if (trollModel.getImage().isEmpty()) {
trollViewHolder.thrillersimage.setVisibility(View.GONE);
} else {
trollViewHolder.thrillersimage.setVisibility(View.VISIBLE);
Picasso.get().load(trollModel.getImage())
.into(trollViewHolder.thrillersimage);
}

Recyclerview in fragment. Not updating after Activity has been closed

I am using a view pager with three tabs (three fragments). In one of these fragments I have a recycler view. The items in this recycler view get updated every 2 seconds from the web. When I first start up the app, the recycler view runs just fine. Even when navigating to different tabs or navigating out of my app with home button, it all works.
However when I close the app by using the backkey and then go into my app again, the recycler view is not updating anymore. It shows the status that it had when the app quit. I monitor the adapter via the console and it keeps on working with the correct data, only the recycler view doesn't show this. I tried all kinds of stuff to "reconnect" adapter and recycler view but it won't work. I am having this issue for days. Any idea for the cause of this problem? See the relevant code for troubleshooting. Thank you!
public class UserAreaFragment extends Fragment implements PopupMenu.OnMenuItemClickListener {
private RecyclerView mRecyclerview;
private UserAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutmanager;
private Handler mainHandler = new Handler();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_user_area, container, false);
...
mAdapter = new UserAdapter(getActivity(), UserDataSingleton.getUserList());
mRecyclerview = root.findViewById(R.id.userListing);
mRecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerview.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new UserAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
...
}
});
}
//Somewhere in my method that receives the data from an online DB:
UserDataSingleton.getUserList().clear();
UserDataSingleton.getUserList().addAll(serverResponse);
mainHandler.post(updateUi);
//And finally the updateUi method: this is essential just sorting and then notifydatasetchanged
Runnable updateUi = new Runnable() {
#Override
public void run() {
Collections.sort(UserDataSingleton.getUserList(), new Comparator<UserItem>() {
#Override
public int compare(UserItem lhs, UserItem rhs) {
// -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
return Double.parseDouble(lhs.getmDistance()) > Double.parseDouble(rhs.getmDistance()) ? 1 : Double.parseDouble(lhs.getmDistance()) < Double.parseDouble(rhs.getmDistance()) ? -1 : 0;
}
});
mAdapter.notifyDataSetChanged();
}
};
//and this is my Adapter:
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
private UserAdapter.OnItemClickListener mListener;
private Context mContext;
private List<UserItem> mUserlist;
public UserAdapter(Context context,List<UserItem> userList){
mUserlist=userList;
mContext = context;
}
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(UserAdapter.OnItemClickListener listener) {
this.mListener = listener;
}
public static class UserViewHolder extends RecyclerView.ViewHolder{
public TextView mUsername;
public TextView mDistance;
public ImageView userIcon;
public UserViewHolder(#NonNull View itemView, final UserAdapter.OnItemClickListener listener) {
super(itemView);
mUsername = itemView.findViewById(R.id.tvNearUsername);
mDistance = itemView.findViewById(R.id.tvDistance);
userIcon = itemView.findViewById(R.id.usericon);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null){
int position = getAdapterPosition();
if (position!= RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
#NonNull
#Override
public UserAdapter.UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View v= inflater.inflate(R.layout.user_item, parent, false);
UserViewHolder uvh= new UserViewHolder(v,mListener);
return uvh;
}
#Override
public void onBindViewHolder(#NonNull UserAdapter.UserViewHolder holder, int position) {
UserItem currentitem = mUserlist.get(position);
holder.mUsername.setText(currentitem.getmNearUsername());
if (currentitem.isArea()){
holder.mDistance.setVisibility(View.INVISIBLE);
holder.userIcon.setImageResource(R.drawable.ic_placeicon);
}else{
holder.mDistance.setVisibility(View.VISIBLE);
}
int distToNextTen = ((Integer.parseInt(currentitem.getmDistance())+5)/10)*10+10;
holder.mDistance.setText("< "+distToNextTen+"m");
}
#Override
public int getItemCount() {
return mUserlist.size();
}
}
I tried to only display the lines that affect the issue for better readability. If you need to see more code just let me know. Thankful for this great community!
(I think problem might be in connection with the main Handler not pointing to the correct view or maybe an issue with adapter-recyclerview connection but I can't find a solution tried so many things already)
Ok I found the problem. It had something to do with my runnables and handlers not being declared within onCreate. Somehow that messed it up. I made a major reconstruction of my code to solve it so its hard to tell which line exactly was the problem but if you are facing a similar problem check that your runOnUi and handler declarations happen in the right places.

Implement onclick in Scrolling Recycleview

I have recycleview which is set to auto scroll. I am looking to implement onclicklistener such that new activity will open.
Here is my Recycleview
final int duration = 10;
final int pixelsToMove = 30;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Runnable SCROLLING_RUNNABLE = new Runnable() {
#Override
public void run() {
top.smoothScrollBy(pixelsToMove, 0);
mHandler.postDelayed(this, duration);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
top = (RecyclerView) view.findViewById(R.id.top);
final LinearLayoutManager llm = new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL,false);
top.setLayoutManager(llm);
top.setHasFixedSize(true);
staggeredBooksAdapter = new TopAdapter(this, bookslist);
top.setAdapter(staggeredBooksAdapter);
//Recycleview
top.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState); }
#Override public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int lastItem = llm.findLastCompletelyVisibleItemPosition();
if(lastItem == llm.getItemCount()-1){
mHandler.removeCallbacks(SCROLLING_RUNNABLE);
Handler postHandler = new Handler();
postHandler.postDelayed(new Runnable() {
#Override
public void run() {
top.setAdapter(null);
top.setAdapter(staggeredBooksAdapter);
mHandler.postDelayed(SCROLLING_RUNNABLE, 6000);
}}, 6000);
}
}
});
mHandler.postDelayed(SCROLLING_RUNNABLE, 6000);
and my adapter class is
public class TopAdapter extends RecyclerView.Adapter<TopAdapter.MyViewHolder> {
ArrayList<location> bookslist;
CardView cv;
location g;
private Home context;
public TopAdapter(Home context, ArrayList<location> bookslist){
this.bookslist = bookslist;
this.context = context; // add this as a field in your adapter class.
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_top,parent,false);
return new MyViewHolder(v);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView teacher_name,teacher_location;
LinearLayout profile_details;
ImageView iv;
MyViewHolder(final View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.teacher_name);
teacher_location = (TextView)
}
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
database = FirebaseDatabase.getInstance();
g = bookslist.get(position);
holder.teacher_name.setText(g.getSellername());
holder.profile_details.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
g = bookslist.get(position);
Intent intent = new Intent(v.getContext(), gender_details.class);
intent.putExtra(KEY_NAME, g.getSellername());
v.getContext().startActivity(intent);
}
});
#Override
public int getItemCount() {
return bookslist.size();
}
}
When I repetitively click, I am able to opens new activity with details based on position but I have no idea how It is happening and I can only reproduce same effect only after repeatedly clicking some item. But it doesn't happen often. I'm looking for permanent solution to opens new activity when I click any item from list of recycleview in one click.
Thanks in advance.
Your onClickListener setted for view with name profile_details and it is triggered only when you tap on (exactly) this view. Some of your elements may overlap this view, so your tap not work. It's explain what your startActivity triggered after some random number of taps in different parts of item.
Try to debug clicks on view and set this onItemClickListener to appropriate View/ViewGroup
P.S:
Also my advice is to not store any database related objects inside adapter (it's violation of single responsibility).
Also is bad practice to store activity start logic in adapter. See this answer: Can't resolve the Context or Application while navigating from Adapter of a fragment(A) to another Fragment (B)
Hope it will help :)

How can I do two text blocks in the listView which the first in the left alignment and the second in the right?

How can I set two text blocks in the listView, of which the first is on the left, the other on the right? I am tried to create a new layout with two textViews. But I don't know how I can connect textViews with listView and how I can set texts on textViews. May anybody help me?
I would like to have a list like this
Assuming you have the list and your layout with those 2 textview is ready just use this adapter and set this adapter to recycler view of the activity. let me know if you face any issues
public class CountryCodeAdapter extends RecyclerView.Adapter<CountryCodeAdapter.ViewHolder> {
private CountryCodeActivity activity;
ArrayList<CountryCodeModel> list = new ArrayList<>();
int selected_pos = 0;
public CountryCodeAdapter(CountryCodeActivity activity, ArrayList<CountryCodeModel> list) {
this.activity = activity;
this.list = list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_country_listing, parent, false);
return new ViewHolder(rootView);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.tv_row_CountryCodeActivity_countrycode.setText(list.get(holder.getAdapterPosition()).getDial());
holder.tv_row_CountryCodeActivity_countryname.setText(list.get(holder.getAdapterPosition()).getName());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("country_code", list.get(holder.getAdapterPosition()).getDial());
activity.setResult(activity.RESULT_OK, intent);
activity.finish();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_row_CountryCodeActivity_countryname,
tv_row_CountryCodeActivity_countrycode;
public ViewHolder(View itemView) {
super(itemView);
tv_row_CountryCodeActivity_countryname = itemView.findViewById(R.id.tv_row_CountryCodeActivity_countryname);
tv_row_CountryCodeActivity_countrycode = itemView.findViewById(R.id.tv_row_CountryCodeActivity_countrycode);
tv_row_CountryCodeActivity_countryname.setTypeface(AppClass.Lato_Regular);
tv_row_CountryCodeActivity_countrycode.setTypeface(AppClass.Lato_Regular);
}
}
}
1)You should use RecyclerView insteaad of listView, and for recyclerView you can achieve what you want with item decorator.
2)But if you have to use ListView(which is less possible case) you can do this by checking list item position and set the corresponding margin to the layout which is not recomended.
3)Also there is another way to achieve this, which is to use different layout resource xml files, but I would not use the last two variants. I would prefer the first.

How can I load images using Picasso from a RecyclerAdapter?

I'm trying to load thumbnail images in a ImageView contained in a RecyclerAdapter Picasso.with(context).load(stringUrl).into(imageView); but this requires a Context. From the RecyclerAdapter is it possible to get the Context of my app's MainActivity? Do I want to do this, or should I be loading the image elsewhere?
These are my classes. The RecyclerAdapater doesn't compile, of course, but it represents what I'm trying to do.
MainActivity:
public class MainActivity extends AppCompatActivity implements MainScreenContract.View {
ArrayList<String> list;
// Objects for RecyclerView
private RecyclerView recyclerView;
private RecyclerView.Adapter recyclerAdapter;
private RecyclerView.LayoutManager recyclerLayoutManager;
#Inject
MainScreenPresenter mainPresenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Timber.plant(new Timber.DebugTree() {
// Add the line number to the tag
#Override
protected String createStackElementTag(StackTraceElement element) {
return super.createStackElementTag(element) + ':' + element.getLineNumber();
}
});
// RecyclerView implementation
recyclerView = (RecyclerView) findViewById(R.id.my_list);
// set to true because all images will be the same size
recyclerView.setHasFixedSize(true);
recyclerLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(recyclerLayoutManager);
DaggerMainScreenComponent.builder()
.netComponent(((App) getApplicationContext()).getNetComponent())
.mainScreenModule(new MainScreenModule(this))
.build().inject(this);
//Call the method in MainPresenter to make Network Request
mainPresenter.loadVideo();
}
#Override
public void showVideos(Video video){
// Loop through the posts, get the title of the post, and add it to our list object
// TODO: Simplify these references with a variable?
for(int i = 0; i < video.getResults().size(); i++){
// TODO: add second for loop, or simplyfy and get rid of Video object
list.add(video.getResults().get(i).getSiteDetailUrl());
//list.add(video.get(i).getSiteDetailUrl());
Timber.d("List item " + i + " = " + list.get(i));
}
// RecyclerView implementation
recyclerAdapter = new MainScreenRecyclerAdapter(list);
recyclerView.setAdapter(recyclerAdapter);
}
#Override
public void showError(String message){
// Show error message text as a Toast message
Toast.makeText(getApplicationContext(), "Error" + message, Toast.LENGTH_SHORT).show();
Timber.e("Error: " + message);
}
#Override
public void showComplete(){
// Show completed Toast message
Toast.makeText(getApplicationContext(), "Complete", Toast.LENGTH_SHORT).show();
}
}
RecyclerAdapter:
public class MainScreenRecyclerAdapter extends RecyclerView.Adapter<MainScreenRecyclerAdapter.ViewHolder> {
private List<String> dataset;
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public ViewHolder(ImageView v) {
super(v);
imageView = v;
}
}
// TODO: Should I make the list contain Video/Result objects and pull the data from that?
public MainScreenRecyclerAdapter(List<String> dataset) {
dataset = dataset;
}
// Create new views
#Override
public MainScreenRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
ImageView v = (ImageView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.thumbnail_view, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from dataset at this position
// - replace the contents of hte view with that element
// TODO: Call to picasso to load image into holder.imageView
String imageUrl = dataset.get(position);
Timber.d("Image URL: " + imageUrl);
ImageView view = holder.imageView;
Picasso.with(MainActivity.context).load(imageUrl).into(view);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return dataset.size();
}
}
Thanks!
you need to pass the context as a constructor argument and then use this context
private Context mContext;
public MainScreenRecyclerAdapter (Context context) {
mContext = context;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String imageUrl = dataset.get(position);
Timber.d("Image URL: " + imageUrl);
ImageView view = holder.imageView;
Picasso.with(MainActivity.context).load(imageUrl).into(view);
}

Categories

Resources