How to Delete Listview Item Using ImageView as OnClick Event - java

Ok, I have an Listview adapter that contains an ImageView, TextView and another ImageView in that order. So I want to be able to delete the item in list when user presses on second ImageView. When the user press on the item in list it will start TextToSpeech and it will say what is inside TextView. But if the user wants to remove the entry he/she will press on second ImageView which is a delete icon, at that point the item will be remove from the list. Starting the click listener for the imageview is not a problem, the problem is how do I get the number (int) of the corresponding item in listview adapter so I can remove it from array. Here's xml list_item.xml for single entry in list
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp">
<ImageView
android:id="#+id/item_icon_imageview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.15"
android:src="#drawable/ic_record_voice_24dp2"/>
<TextView
android:id="#+id/phrase_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.80"
android:textSize="20sp"
android:layout_marginTop="5dp"
android:text="My phone number is 305 666 8454"/>
<ImageView
android:layout_gravity="center"
android:id="#+id/delte_item_imageview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.10"
android:src="#drawable/ic_delete_black_24dp"/>
</LinearLayout>
</RelativeLayout>
The fragment for inflating the listview
public class CustomFragment extends Fragment {
private ArrayAdapter<String> adapter;
private ListView listView;
private FloatingActionButton addPhraseButton;
private TextView phraseTitleTextView;
private TextToSpeech textToSpeech;
private ArrayList<String> phrases;
private static final String PHRASE_LABEL = " Phrases";
private static final String CATEGORY_KEY = "categories";
private ImageView deleteItemImageView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_custom, container, false);
final String categories;
//if we selecte a category sent from home fragment else we got here through menu
Bundle arguments = getArguments();
if (arguments != null && arguments.containsKey(CATEGORY_KEY)) {
categories = arguments.getString(CATEGORY_KEY).toLowerCase();
}
else {
Resources res = view.getResources();
categories = res.getStringArray(R.array.categories)[0].toLowerCase();
}
final Phrases allPhrases = Phrases.getPhrases();
allPhrases.fetchAllPhrases(view.getContext());
phrases = allPhrases.getAllPhrases().get(categories);
phraseTitleTextView = view.findViewById(R.id.label_phrases_txtview);
deleteItemImageView = view.findViewById(R.id.delte_item_imageview);
phraseTitleTextView.setText(categories.substring(0,1).toUpperCase() +
categories.substring(1)+ PHRASE_LABEL);
addPhraseButton = view.findViewById(R.id.add_phrases_btn);
// setting local for text to speech
textToSpeech = new TextToSpeech(getActivity().getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
textToSpeech.setLanguage(Locale.US);
}
});
//setting adapter and listview
adapter = new ArrayAdapter<String>(getContext(), R.layout.entry_item, R.id.phrase_textview, phrases);
listView = (ListView) view.findViewById(R.id.phrases_list);
listView.setAdapter(adapter);
listView.setItemsCanFocus(true);
//activating text to speech when user selects item in listview
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> paren, View view, int position, long id) {
String text = phrases.get(position);
Toast.makeText(getContext(), text, Toast.LENGTH_LONG).show();
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH,null, null);
}
});
deleteItemImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
//button to display alert dialog box to add new phrase
addPhraseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addPhraseDialogBox();
}
});
return view;
}
}

You can achieve this through Custom Adapter. Check below:
public class CustomArrayAdapter extends ArrayAdapter<String> {
LayoutInflater inflater;
ArrayList<String> phrases;
public CustomArrayAdapter(Context context, int textViewResourceId, ArrayList<String> items) {
super(context, textViewResourceId, items);
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
phrases = items;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.entry_item, parent, false);
}
....
ImageView deleteItemImageview = (ImageView) convertView.findViewById(R.id. delte_item_imageview);
deleteItemImageview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
phrases.remove(position);
notifyDataSetChanged();
}
});
return convertView;
}
}

Related

SearchView show me wrong matches

I have a SearchView and a ListView. My goal here is when I search for (for example) Toyota, I got result in the ListView with Toyota, and than when I click on it, Toyota save to another list.
Everything is working well, except the ListView. When I search for something, I get different result. For example if I search for Toyota, I got BMW or Mazda etc. but not Toyota. BUT, if I click on this result Toyota will be saved and not BMW or Mazda despite I click on them.
I think something with the ListView is not good, because in the background evertyhing is working well, but it's shown otherwise.
Here is my xml file:
<SearchView
android:id="#+id/search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false">
<requestFocus />
</SearchView>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
I am using a custom row in my ListView, I don't think its affect any harm, but now I am even questioning my own existence :D So here it is the list_row.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:padding="15sp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/name"
android:layout_centerVertical="true"
android:layout_marginLeft="28sp"
android:textColor="#73c993"/>
</RelativeLayout>
And the ListViewAdapter.java:
public class ListViewAdapter extends ArrayAdapter<String> {
ArrayList<String> list;
Context context;
public ListViewAdapter(Context context, ArrayList<String> items) {
super(context, R.layout.list_row, items);
this.context = context;
list = items;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_row, null);
TextView name = convertView.findViewById(R.id.name);
name.setText(list.get(position));
}
return convertView;
}
}
Finally, my HomeFragment.java:
public class HomeFragment extends Fragment implements SearchView.OnQueryTextListener {
SearchView editsearch;
static ListView listView;
static ListViewAdapter adapter;
static ArrayList<String> cars, selectedCars;
static Context context;
private HomeViewModel homeViewModel;
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
return inflater.inflate(R.layout.fragment_home, container, false);
}
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
listView = (ListView) view.findViewById(R.id.list);
cars = new ArrayList<>(Arrays.asList("Toyota", "BMW", "Mazda"));
selectedCars= new ArrayList<>();
context = getContext();
adapter = new ListViewAdapter(context, cars);
listView.setAdapter(adapter);
editsearch = (SearchView) view.findViewById(R.id.search);
editsearch.setOnQueryTextListener(this);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = adapter.getItem(position);
if (!(selectedCars.contains(item))) {
addItem(item);
makeToast(item + " added.");
} else {
makeToast(item + " already added.");
}
}
});
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}

Change style of only one item spinner android

I defined a spinner like this, with its own adapter.
How can I change the style of only one item of the spinner?
In particular I would like to change the color of the last string inserted in the spinner.
Thanks
Spinner spinner = findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, "List<String>");
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
You can create custom adapter for spinner, in adapter inside getView add a condition when a position is the last one, change a view(TextView) background color.
UPDATE :
create customAdapter
public class CustomAdapter extends BaseAdapter {
private final Context context;
private final List<String> list;
public CustomAdapter(#NonNull Context context, #NonNull List<String> list) {
this.context = context;
this.list = list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view;
if (convertView == null) {
view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
} else {
view = convertView;
}
TextView textView = view.findViewById(R.id.textView_name);
textView.setText(list.get(position));
if (position == list.size() - 1) {
textView.setBackgroundResource(android.R.color.holo_blue_light);
}
return view;
}
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/textView_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:gravity="center"
android:textStyle="bold"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
then set customAdpater to spinner
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<String> list = new ArrayList<String>();
list.add("first");
list.add("second");
list.add("third");
list.add("forth");
Spinner spinner = findViewById(R.id.spinner);
CustomAdapter adapter = new CustomAdapter(this, list);
spinner.setAdapter(adapter);
}
result will be as the photo

fragment showing but recycler view isn't

The button view shows confirming that the fragment shows, however the recycler view doesn't.
The logged array size of "jobs" is 1, confirming that getItemCount() isn't the problem and that the recycler adapter constructor is called. I'm reusing my JobRecyclerAdapter class but nothing's static, so there shouldn't be any interference between the two instances. The layout is a a copy of a working one I have, minus different ids and layout name, so that shouldn't be a problem either. There are no errors.
Layout
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<include layout="#layout/top_bar"
android:id="#+id/topBarAJ"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"/>
<include layout="#layout/bottom_bar"
android:id="#+id/bottomBarAJ"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/activeJobRecyclerView"
app:layout_constraintTop_toBottomOf="#id/topBarAJ"
app:layout_constraintBottom_toTopOf="#id/bottomBarAJ"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/activeJobRecyclerView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.505"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/topBarAJ" />
</androidx.constraintlayout.widget.ConstraintLayout>
RecyclerAdapter
List<Job> jobs;
List<Drawable> images;
RecyclerViewClickListener clickListener;
public JobRecyclerAdapter(List<Job> downloadedJobs, List<Drawable> images, RecyclerViewClickListener clickListener) {
this.jobs = downloadedJobs;
this.images = images;
Integer arraySize = images.size();
Log.d("downloadActiveJob", "JobRecyclerAdapter: images array size: " + arraySize.toString());
arraySize = jobs.size();
Log.d("downloadActiveJob", "JobRecyclerAdapter: jobs array size: " + arraySize.toString());
this.clickListener = clickListener;
}
class JobCardViewHolder extends RecyclerView.ViewHolder {
public ImageView itemImage;
public TextView itemName;
public TextView itemWeight;
public TextView itemSize;
public TextView transmitterName;
public JobCardViewHolder(View v) {
super(v);//call default constructor
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("RecyclerView", "onClick:" + getAdapterPosition());
clickListener.recyclerViewListClicked(v, getAdapterPosition());
}
});
itemImage = (ImageView) v.findViewById(R.id.itemImage);
itemName = (TextView) v.findViewById(R.id.itemName);
itemWeight = v.findViewById(R.id.itemWeight);
itemSize = v.findViewById(R.id.itemSize);
transmitterName = v.findViewById(R.id.transmitterName);
}
}
public void removeItem(int jobIndex) {
jobs.remove(jobIndex);
notifyDataSetChanged();
}
#Override
public JobCardViewHolder onCreateViewHolder(ViewGroup vg, int n) {
View v = LayoutInflater.from(vg.getContext()).inflate(R.layout.job_card_layout, vg, false);
JobCardViewHolder vH = new JobCardViewHolder(v);
return vH;
}
#Override
public void onBindViewHolder(JobCardViewHolder vH, int position) {
vH.itemName.setText(jobs.get(position).itemName);
vH.itemImage.setImageDrawable(images.get(position));
vH.itemWeight.setText(jobs.get(position).itemWeight);
vH.itemSize.setText(jobs.get(position).itemSize);
vH.transmitterName.setText(jobs.get(position).transmitterName);
}
#Override
public int getItemCount() {
return jobs.size();
}
}
Fragment (I only showed the relevant parts of the fragment.)
RecyclerView jobRecyclerView;
JobRecyclerAdapter jobRecyclerAdapter;
LinearLayoutManager llm;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.sub_fragment_active_jobs_1, container, false);
this.jobRecyclerView = view.findViewById(R.id.activeJobRecyclerView);
return view;
}
public void configureJobsRecyclerAdapter(Job activeJob, List<Drawable> imageDrawables) {
Log.d("downloadActiveJob", "configureJobRecyclerAdapter called");
List<Job> downloadedJobs = new ArrayList<>();
downloadedJobs.add(activeJob);
Integer arraySize = imageDrawables.size();
Log.d("downloadActiveJob", "configureJobRecyclerAdapter: " + arraySize.toString());
jobRecyclerAdapter = new JobRecyclerAdapter(downloadedJobs, imageDrawables, this);
llm = new LinearLayoutManager(context);
jobRecyclerView.setLayoutManager(llm);
jobRecyclerView.setAdapter(jobRecyclerAdapter);
}
Update: If I move the recycler view/adapter setup code to onResume, the recycler view is visible. When I update the recycler view with a new adapter, the recycler view becomes invisible.
If I can't solve it using this new discovery I'll post the whole fragment.
Hey, you create the function configureJobsRecyclerAdapter() but didn't call it inside fragment onCreateView(). Like...
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.sub_fragment_active_jobs_1, container, false);
this.jobRecyclerView = view.findViewById(R.id.activeJobRecyclerView);
configureJobsRecyclerAdapter()//Add this line.
return view;
}
if you are fetching data which are required for configureJobsRecyclerAdapter() from an api maybe you are setting empty list at the time when you are calling configureJobsRecyclerAdapter(). and that's why when you call it in onResume, the list becomes visible(because then data is fetched).
and don't forget to call adapter.notifyDataSetChanged() after each change in your list.

android search view on grid view with images does not give correct search result.

I am trying to implement a search function for android's grid view. However, every time i search a image , i do not get the correct image with its text. Below is my code. Any help is greatly appreciated :) My filter logic seems to be correct based on the log statements that i printed out. However the image and text is not filtered correctly.
MainActivity.
public class MainActivity extends AppCompatActivity {
final String TAG = "MainActivity";
GridView searchGrid;
ImageAdapter adapter;
int[] resourceIds = new int[]{R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2,
R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5};
String[] names = new String[]{"sample 0", "sample 1", "sample 2", "sample 3", "sample 4",
"testImage"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchGrid = findViewById(R.id.searchGrid);
adapter = new ImageAdapter(this, this.getModels());
searchGrid.setAdapter(adapter);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem item = menu.findItem(R.id.search_food);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
adapter.filter(s);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
private List<DataModel> getModels() {
List<DataModel> models = new ArrayList<>();
DataModel dm;
for (int i = 0; i < names.length; i++) {
dm = new DataModel(resourceIds[i], names[i]);
models.add(dm);
}
return models;
}
class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<DataModel> dataModels;
private List<DataModel> filterList = new ArrayList<>();
public ImageAdapter(Context context, List<DataModel> dataModels) {
mContext = context;
this.dataModels = dataModels;
this.filterList.addAll(dataModels);
}
#Override
public int getCount() {
return dataModels.size();
}
#Override
public Object getItem(int i) {
return dataModels.get(i);
}
#Override
public long getItemId(int i) {
return dataModels.indexOf(getItem(i));
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView imageView;
if (view == null) {
// if it's not recycled, initialize some attributes
view = layoutInflater.inflate(R.layout.single_item, null);
imageView = view.findViewById(R.id.imageView);
TextView textView = view.findViewById(R.id.textView);
imageView.setImageResource(dataModels.get(i).resourceId);
textView.setText(dataModels.get(i).imageName);
}
return view;
}
public void filter(CharSequence text) {
String query = text.toString().toLowerCase();
//Log.i(TAG,query);
dataModels.clear();
if (text.length() == 0 ) {
dataModels.addAll(filterList);
} else {
for (DataModel dm : filterList) {
if (dm.imageName.toLowerCase().contains(query)) {
Log.i(TAG,dm.imageName + " " + query);
dataModels.add(dm);
}
}
}
notifyDataSetChanged();
}
}
MainActivity xml file.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<GridView
android:padding="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/searchGrid"
android:numColumns="auto_fit"
android:columnWidth="120dp"
android:gravity="center">
</GridView>
</RelativeLayout>
single_item xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageView" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView"
android:layout_below="#+id/imageView"
android:layout_alignStart="#+id/imageView"
android:layout_alignEnd="#+id/imageView"
/>
search_manu xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/search_food"
android:title="Search Myfoods"
android:icon="#android:drawable/ic_menu_search"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always">
</item>
Try to change your code like this. Maybe it helps.
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView imageView;
if (view == null) {
// if it's not recycled, initialize some attributes
view = layoutInflater.inflate(R.layout.single_item, null);
}
imageView = view.findViewById(R.id.imageView);
TextView textView = view.findViewById(R.id.textView);
imageView.setImageResource(dataModels.get(i).resourceId);
textView.setText(dataModels.get(i).imageName);
return view;
}
Your filter code is alright but you are not displaying the items properly. Even when your view is already initialized you need to fill correct data in the views else the view will show previous items data. Modify your code like this
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (view == null) {
view = layoutInflater.inflate(R.layout.single_item, null);
}
ImageView imageView = view.findViewById(R.id.imageView);
TextView textView = view.findViewById(R.id.textView);
imageView.setImageResource(dataModels.get(i).resourceId);
textView.setText(dataModels.get(i).imageName);
return view;
}
Also try using holder pattern so that you don't have to find view by its id everytime. It will save some run time on UI thread

Android - Custom adapter with imageview and textview not displaying listview

I am working on a college project to build an android based mobile learning app. I'm using Parse for backend services. There is a class, namely 'Course' which contains name of the courses to be offered along with an icon for each course. I have written code for custom adapter to display a list of all the courses with icons. The project is executing but the list is not appearing. I cannot figure out what is going wrong.
Here is my SelectCourse.java code
final List<Item> items=new ArrayList<Item>();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Course");
query.orderByAscending("name");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
if (list.size() > 0)
for (int i = 0; i < list.size(); i++) {
final String course = list.get(i).getString("name");
ParseFile image = list.get(i).getParseFile("image");
//adapter.add(course.getString("name"));
image.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
Bitmap icon = BitmapFactory.decodeByteArray(
data, 0, data.length);
Item item = new Item(icon, course);
items.add(item);
} else {
Toast.makeText(getApplicationContext(),
e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
}
} else {
Toast.makeText(getApplicationContext(),
e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
CustomAdapter adapter=new CustomAdapter(this,items);
ListView listView = (ListView) findViewById(R.id.course_list);
listView.setAdapter(adapter);
This is my CustomAdapter.java code
public class CustomAdapter extends BaseAdapter {
private Context context;
private List<Item> list;
CustomAdapter(Context context, List<Item> list){
this.context = context;
this.list = list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView=convertView;
if(rowView==null) {
ViewHolder viewHolder = new ViewHolder();
LayoutInflater layoutInflater = (LayoutInflater) context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = layoutInflater.inflate(R.layout.list_select_course, parent, false);
viewHolder.icon = (ImageView) rowView.findViewById(R.id.rowImageView);
viewHolder.text = (TextView) rowView.findViewById(R.id.rowTextView);
rowView.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) rowView.getTag();
viewHolder.icon.setImageBitmap(list.get(position).image);
viewHolder.text.setText(list.get(position).text);
return rowView;
}}
Here are ViewHolder and Item
public class ViewHolder {
ImageView icon;
TextView text;}
public class Item {
Bitmap image;
String text;
Item(Bitmap image, String text){
this.image=image;
this.text=text;
}}
This is content_select_course.xml
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.rsa.minerva.SelectCourseActivity"
tools:showIn="#layout/app_bar_select_course">
<ListView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/course_list"
android:layout_weight="1" />
And finally list_select_course.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="16dp">
<ImageView
android:id="#+id/rowImageView"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:id="#+id/rowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/colorButton"
android:text="Hello World"/>
This part of the code:
query.findInBackground(new FindCallback<ParseObject>()
Doesn't run synchronously, meaning that you are actually creating an adapter with no data:
Put this snippet before you call the query.findInBackground():
CustomAdapter adapter=new CustomAdapter(this,items);
ListView listView = (ListView) findViewById(R.id.course_list);
listView.setAdapter(adapter);
And then inside the public void done() callback, put:
adapter.notifyDataSetChanged();
After you add the items to the list with items.add(item).
That should do it.

Categories