Change style of only one item spinner android - java

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

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;
}

How to Delete Listview Item Using ImageView as OnClick Event

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;
}
}

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.

Populate ListView from List<Object>

Basically I have a list of objects of class Ingredient which looks like this:
class Ingredient {
public int id;
public String name;
public Ingredient(String name) {
this.name = name;
}
}
so each object from list have a name.
Now to use ArrayAdapter I need to have a List of strings filled with names.
Is there any way to use ArrayAdapter with my list of Ingredients?
This is how it looks right now
List<Ingredient> ingredientsList= new ArrayList<Ingredient>();
ingredientsList.add(new Ingredient("foo"));
ingredientsList.add(new Ingredient("bar"));
Use the below. You can use a for loop and populate your ingredientsList. The below is just a example
List<Ingredient> ingredientsList= new ArrayList<Ingredient>();
Ingredient i= new Ingredient("foo");
ingredientsList.add(i);
Ingredient i1= new Ingredient("bar");
ingredientsList.add(i1);
Then
ListView lv = (ListView) findViewById(R.id.listview);
// initialize listview
lv.setAdpater(new CustomAdapterArrayAdapter(ActivityName.this,ingredientsList));
// set the custom adapter to listview
You can use a CustomAdapterArrayAdapter inflate a custom layout
public class CustomAarrayAdapter extends ArrayAdapter
{
List<Ingredient> ingredientsList;
public CustomArrayAdapter(Context context, List<Ingredient> list)
{
super(context,0,list);
ingredientList = list;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row,parent,false);
// inflate custom layout called row
holder = new ViewHolder();
holder.tv =(TextView) convertView.findViewById(R.is.textView1);
// initialize textview
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
Ingredient in = (Ingredient)ingredientsList.get(position);
holder.tv.setText(in.name);
// set the name to the text;
return convertView;
}
static class ViewHolder
{
TextView tv;
}
}
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
ViewHolder is for smooth scrolling and performance
row.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="28dp"
android:text="TextView" />
</RelativeLayout>
Edit:
Without using custom adapter
class Ingredient {
public int id;
public String name;
public Ingredient(String name) {
this.name = name;
}
#Override
public String toString() {
// TODO Auto-generated method stub
return this.name.toString();
}
}
Then
public class MainActivity extends Activity {
List<Ingredient> ingredientsList= new ArrayList<Ingredient>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for(int i=0;i<10;i++)
{
ingredientsList.add(new Ingredient("foo"+i));
}
ArrayAdapter<Ingredient> adapter = new ArrayAdapter<Ingredient>(this,android.R.layout.simple_list_item_1,ingredientsList);
ListView lv= (ListView) findViewById(R.id.listView1);
lv.setAdapter(adapter);
}
}
Then
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true" >
</ListView>
</RelativeLayout>
Snap
Extend the array adapter class:
public class MyAdapter extends ArrayAdapter<Ingredient> {
Activity activity;
public MyAdapter(Activity context, int resource,
List<Ingredient> objects) {
super(context, resource, objects);
this.activity = context;
}
public View getView(int position, View convertView, ViewGroup parent) {
Ingredient currentIngredient = getItem(position);
//Do Something
....
}

add unique images to spinner rows in android

I have managed to code to have images in each row of spinner but the images are all the same.I want to change each image. how do you do that. here is my xml and the code
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/calendar"/>
<TextView
android:id="#+id/weekofday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
here is java
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, R.layout.row, R.id.weekofday, list);
dataAdapter.setDropDownViewResource(R.layout.row);
spinner.setAdapter(dataAdapter);
it displays the same image because it is set in the row.xml file. how do I make it dynamic?
Why don't you create Custom adapter and write the code accordingly. As far as I understand that , its showing same image because you have set it in row.xml. But how would adapter will know that the image should be changed on each row.
In Custom Adapter you can set the image as per the position (i.e. index) of Spinner Item
public class SavedSearchAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<SavedSearch> mData;
private boolean isEditMode = false;
public SavedSearchAdapter(Context context , ArrayList<SavedSearch> data){
mContext = context;
mData = data;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
TextView tvTitle;
ImageView ivDelete;
if(convertView == null){
view = View.inflate(mContext, R.layout.screen_saved_search_item_row, null);
}
else{
view = convertView;
}
tvTitle = (TextView) view.findViewById(R.id.screen_saved_search_item_row_tv);
tvTitle.setText(mData.get(position).name);
ivDelete = (ImageView) view.findViewById(R.id.screen_saved_search_item_row_iv_delete);
view.setTag(mData.get(position));
return view;
}
}

Categories