While using a ViewPager i noticed that it wouldn't respond very quickly, meaning that it slows down when switchting through fragments, kind of in a laggy way.
Does anyone know how this code could be causing the issue?
public class List_adapter : BaseAdapter<Element>
{
public List<Element> _list;
FragmentOne _context;
public List_adapter(FragmentOne context, List<Element> list)
{
super(context, list);
_list = list;
_context = context;
}
#Override
public int getCount()
{
return _list.size();
}
#Override
public Object getItem(int position)
{
return _list.get(position);
}
#Override
public long getItemId(int position)
{
return getItem(position).hashCode();
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater)getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.row, parent, false);
Element item = getItem(position);
TextView lbl = (TextView)view.findViewById(R.id.label);
TextView prop = (TextView)view.findViewById(R.id.Prop);
lbl.setText(item.getlabel());
prop.setText(item.getprop());
return view;
}
}
Use ViewHolder pattern for smooth list scrolling
Implement Offscreen page limit for initialising a view before showing it inside ViewPager
Related
I am trying to display a ListView of some docs and images with different layouts.
it worked for docs but images are still not showing.
I have used the .contains method to check if the item is doc or image. Help me with this.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = activity.getLayoutInflater();
String fileName = uriList.get(position).getFileName();
return viewSetup(position, layoutInflater, fileName);
}
private View viewSetup(final int position, LayoutInflater layoutInflater, String fileName) {
if (fileName.contains(".png") || fileName.contains(".jpg") || fileName.contains(".jpeg")) {
View inflate = layoutInflater.inflate(R.layout.main_list_item_img, null, false);
ImageView imageView = inflate.findViewById(R.id.imgPrev);
Glide.with(activity).load(uriList.get(position).getDownloadLink()).into(imageView);
itemSetup(position, fileName, inflate);
return inflate;
} else {
View inflate = layoutInflater.inflate(R.layout.main_list_item_docs, null, false);
itemSetup(position, fileName, inflate);
return inflate;
}
}
private void itemSetup(final int position, String fileName, View inflate) {
TextView title = inflate.findViewById(R.id.uriTitle);
TextView desc = inflate.findViewById(R.id.uriDesc);
ImageView download = inflate.findViewById(R.id.download);
TextView createdOn = inflate.findViewById(R.id.createdOn);
title.setText(fileName + "");
desc.setText(uriList.get(position).getDescription());
createdOn.setText(uriList.get(position).getSendTime());
download.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
savefile(uriList.get(position).getDownloadLink());
}
});
}
I think there is a problem in your image loading. You can use Picasso.
Picasso.with(activity).load(yourUrl).
placeholder(R.drawable.image_loader).into(myImage);
You need to use type variable you can check how I did in below example :-
public class JobsAdapter extends BaseAdapter {
private Activity context;
private LinkedList<KeyValuesPair> listItemArrayList;
private LinkedList<Integer> type;
private LayoutInflater inflater;
public JobsAdapter(Activity context, LinkedList<KeyValuesPair> objects, LinkedList<Integer> type) {
this.context = context;
this.listItemArrayList = objects;
this.type = type;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return type.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public boolean isEnabled(int position) {
return type.get(position) != 0;
}
#TargetApi(Build.VERSION_CODES.O)
public View getView(int position, View convertView, ViewGroup parent) {
// used new view instead of convertView so the spinner could support multiple views
View view = null;
// if type is equals to 0 it will load jobs header else jobs child
if (type.get(position) == 0) {
view = inflater.inflate(R.layout.lv_header, null, false);
TextView header = view.findViewById(R.id.jobsHeading);
header.setText(listItemArrayList.get(position).getValue());
if (position == 0) {
header.setTextSize(16);
header.setTypeface(context.getResources().getFont(R.font.raleway_regular));
header.setTextColor(context.getResources().getColor(R.color.colorPrimaryDark));
} else {
header.setTextColor(context.getResources().getColor(R.color.colorBlack));
}
} else if (type.get(position) == 1) {
view = inflater.inflate(R.layout.lv_child, null, false);
TextView child = view.findViewById(R.id.jobsChild);
child.setText(listItemArrayList.get(position).getValue());
}
return view;
}
}
I have a ListView and a CustomAdapter. The elements are all successfully loaded into the list. Now I want to change the background color of a certain element of the list by clicking on an external button. But I do not know how to access a specific item in the list.
Here is the CustomAdapter class:
public class CustomAdapter extends BaseAdapter {
private Context ctx;
private int resource;
private List<ItemModel> items;
public PreorderListAdapter(Context context, int resource, List<ItemModel> items){
this.ctx = context;
this.resource = resource;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public ItemModel getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#NonNull
#Override
public View getView(int i, View convertView, #NonNull ViewGroup parent) {
View view = convertView;
if(view == null){
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(resource, null);
}
TextView text1 = (TextView) view.findViewById(R.id.text1);
TextView text2 = (TextView) view.findViewById(R.id.text2);
TextView text3 = (TextView) view.findViewById(R.id.text3);
ItemModel item = items.get(i);
text1.setText(item.getName());
text2.setText(item.getOption2());
text3.setText(item.getOption3());
return view;
}
}
You can do it like this inside your getView() method
view.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
view.setBackgroundColor(ContextCompat.getColor(this, R.color.yourcolor));
}
});
If you have a button on your view then performs the listener on that button
If you want to get your selected item view from your parent activity then :
yourlistview.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent,View view, int position, long id)
{
selectedposition = position ;
}
});
View view = listView.getAdapter().getView(selectedposition,null,listview);
Then change its background:
view.setBackgroundColor(ContextCompat.getColor(this, R.color.yourcolor));
please define your color in your color.xml file
If you have more than one view then , create an ArrayList<View> and do some loop
create a custom listener interface in your activity and your
adapter will implement this.
public interface OnClickListenerFromActivity {
void onActivityButtonClick(int position);
}
on click in your button call your listener's method
mOnClickListenerFromActivity.onActivityButtonClick(mList.getItem(yourPostion));
implement this listener into your adapter
public class CustomAdapter extends BaseAdapter implements Activity.OnClickListenerFromActivity {
private Context ctx;
private int resource;
private List<ItemModel> items;
public PreorderListAdapter(Context context, int resource, List<ItemModel> items){
this.ctx = context;
this.resource = resource;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public ItemModel getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#NonNull
#Override
public View getView(int i, View convertView, #NonNull ViewGroup parent) {
View view = convertView;
if(view == null){
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(resource, null);
}
TextView text1 = (TextView) view.findViewById(R.id.text1);
TextView text2 = (TextView) view.findViewById(R.id.text2);
TextView text3 = (TextView) view.findViewById(R.id.text3);
ItemModel item = items.get(i);
text1.setText(item.getName());
text2.setText(item.getOption2());
text3.setText(item.getOption3());
return view;
}
public void onActivityButtonClick(int position) {
// get your item through position and
// set your color here
}
}
I'm getting a variable data sent from activity to my adapter by using
sendData method, but every time when I try to access it in my getView method it resets to 0, please help. I've tried to debug code to check if the data from an activity is passing and it looks ok. I also created a getNumb method but still, the variable resets to 0. Here is my adapter code:
public class WorkoutListAdapterTwo extends BaseAdapter {
private int y;
public WorkoutListAdapterTwo() {
}
public int sendData(int x){
this.y = x;
return y;
}
public int getNumb(){
return this.y;
}
private static LayoutInflater mLayoutInflater = null;
public WorkoutListAdapterTwo(Activity ctx) {
this.mLayoutInflater = ctx.getLayoutInflater();
}
#Override
public int getCount() {
return WorkoutContentTwo.WORKOUTSTWO.size();
}
#Override
public Object getItem(int position) {
return WorkoutContentTwo.WORKOUTSTWO.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
int j = getNumb();
WorkoutTwo workout = (WorkoutTwo) getItem(j);
String [] arrOfStrings = workout.name.split(",");
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.adapter_workout_row, parent, false);
holder = new ViewHolder();
holder.id = (TextView) convertView.findViewById(R.id.workout_id);
holder.name = (TextView) convertView.findViewById(R.id.workout_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Set the content for the ListView row
//holder.id.setText(workout.id);
//holder.name.setText(arrOfStrings[i]);
holder.id.setText(Integer.toString(position+1));
holder.name.setText(workout.ArrList[position]);
// Set the color for the ListView row
holder.id.setBackgroundColor(workout.dark);
holder.name.setBackgroundColor(workout.light);
return convertView;
}
Here I'm adding the code where I'm calling my method:
public void onItemSelected(int position) {
// Start the detail activity for the selected workout ID.
Intent detailIntent = new Intent(this, WorkoutDetailActivityTwo.class);
detailIntent.putExtra(WorkoutDetailFragmentTwo.ARG_WORKOUT_POS, position);
WorkoutListAdapterTwo newAdd = new WorkoutListAdapterTwo();
newAdd.sendData(position);
newAdd.notifyDataSetChanged();
startActivity(detailIntent);
}
Are you notifying your adapter to update views after updating the value? If your sendData() is not called until after the adapter has done it's first draw, you will need to call notifyDataSetChanged() so that the adapter knows there are new values that should be used to update your views.
You have to make a interface or you can a use notifyDataSetChanged depends on the use if you are doing search operation then use the notifyDataSetChanged method but if you want to send some data then
Fragment or activity
public class ExampleFragment extends Fragment implements MyAdapter.SuccessResponse{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.my_layout, container, false);
MyAdapter myAdapter = new MyAdapter(getActivity(), 0);
myAdapter.successResponse = this;
return contentView;
}
#Override
public void onSuccess() {
}
}
The adapter code
class MyAdapter extends ArrayAdapter{
SuccessResponse successResponse;
public MyAdapter(Context context, int resource) {
super(context, resource);
}
public interface SuccessResponse{
void onSuccess();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//ur views
linearLayout.setOnClickListener(new View.OnClickListener{
#Override
public void onClick (View view){
if(successResponse!=null)
successResponse.onSuccess();
}
})
}
}
You can use any type of adapter i am use arrayadaper here.
I am using Image slider inside recycler View Items, each item have view pager and its own image slider, After loading all items in recycler view. first item display image slider inside its view pager, Then i scroll down to other items may be to item 10 or 11 and then i scroll up to first item then view pager destroy all items or fragments inside it and no image has been displayed now . please give me solution for this, my adapter code . Can't User FragmentStatePagerAdapter because not have access to Fragment Manager
private class ViewPagerAdapter extends PagerAdapter {
ArrayList<ImageInfo> allImages=new ArrayList<>();
private ViewPagerAdapter(ArrayList<ImageInfo> allImages){
this.allImages = allImages;
}
#Override
public int getCount() {
return allImages.size();
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
View itemView = LayoutInflater.from(myContext).inflate(R.layout.fragment_big_row_image, container, false);
ImageView imageListing = (ImageView) itemView.findViewById(R.id.imageListing);
//MH: Loading Images in slider
if(allImages.get(position).csImageFull.length()>0)
{
CommonMethods.ShowImage(myContext, imageListing, allImages.get(position).csImageFull);
}
else
{
CommonMethods.ShowImage(myContext, imageListing, allImages.get(position).csImageMedium);
}
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// ((ViewPager) container).removeView((View) object);
// instantiateItem(container,position);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
/*****************************************************************************************************/
Set off screen pages in your viewpager. Offscreen page limit defines how many pages you want to keep in memory in your view pager. Set this number to your desired page count.
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);
Here view pager will keep last visited 2 pages in memory and won't destroy them.
Try Below Code:
public class SliderPagerAdapter extends PagerAdapter {
private Activity activity;
private ArrayList<String> images;
public SliderPagerAdapter(Activity activity) {
this.activity = activity;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
View view = LayoutInflater.from(container.getContext())
.inflate(R.layout.item_slider, container, false);
ImageView allImages = null;
/MH: Loading Images in slider
if(images.get(position).csImageFull.length()>0)
{
CommonMethods.ShowImage(myContext, imageListing, allImages.get(position).csImageFull);
}
else
{
CommonMethods.ShowImage(myContext, allImages, images.get(position).csImageMedium);
}
container.addView(itemView);
return view;
}
public void setData(ArrayList<String> images) {
this.images = images;
notifyDataSetChanged();
}
#Override
public int getCount() {
return images == null ? 0 : images.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object obj) {
return view == obj;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
View view = (View) object;
container.removeView(view);
}
}
Call method setData from activity and set image array.
Adapter.setData(yourData);
I'm trying to implement an Android app for sudoku game, and i created a customized adapter for that. i want make edit text for cells the user is allowed to modify, and textview for cell filled by the program, the number of ediTexts and textViews will be random. how do specify that in the adapter ?
This is my adapter :
public class SodukuAdapter extends BaseAdapter {
ArrayList<String> items;
static Activity mActivity;
private static LayoutInflater inflater = null;
public SodukuAdapter (Activity activity, ArrayList<String> tempTitle,) {
mActivity = activity;
items = tempTitle;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public final int getCount() {
return items.size();
}
#Override
public final Object getItem(int position) {
return items.get(position);
}
#Override
public final long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = null;
v = inflater.inflate(R.layout.item, null);
EditText et = (EditText) v.findViewById(R.id.et);
et.setText(items.get(position));
return v;
}
}
You can place both views in the same parent (e. g. parent is a RelativeLayout or a FrameLayout) so they are on top of each other. Than you simply hide one of them and show the other using setVisibility() in your getView() method of the adapter.
Of course you would need a datasource object which keeps track of whether a view should show the TextView or the EditText:
class SodokuItem {
public boolean isStatic;
public String text;
}
...
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = inflater.inflate(R.layout.item, null);
SodokuItem item = items.get(position);
EditText et = (EditText) v.findViewById(R.id.et);
TextView tv = (TextView) v.findViewById(R.id.tv);
if(item.isStatic){
et.setVisibility(GONE);
tv.setText(item.text);
}else{
tv.setVisibility(GONE);
et.setText(item.text);
}
return v;
}