My android application keeps crashing when I call the dialog containing this spinner, I'm sure my XML is ok
I tried to spot the problem by making the code as a comment and it turns that the problem is with the setAdapter line
Please if anyone can help, it will be so cool.
CountryManager cm = new CountryManager(this);
user = new UserAppManager(this).getUser();
String countries = user.getCountries();
ArrayList<Country> countriesListe = cm.getCountryByCodes(countries);
Spinner countrieSpinner = mDialogStart.findViewById(R.id.sp_countries);
CountriesListAdapter adapter = new CountriesListAdapter(this, R.layout.country_list_item, countriesListe);
countrieSpinner.setAdapter(adapter);
country = user.getDefaultCountry();
int position = adapter.indexOf(country);
Log.w(TAG, "countries::" + countries + "|| country::" + country + " || position::" + position);
countrieSpinner.setSelection(position);
countrieSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
country = Objects.requireNonNull(adapter.getItem(pos)).getCode();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
country = user.getDefaultCountry();
}
code for the adapter list
public class CountriesListAdapter extends ArrayAdapter<Country> {
private final Context context;
//private final String[] values;
private ArrayList<Country> countries;
public CountriesListAdapter(Context context,int ressource,ArrayList<Country> countries) {
super(context, ressource, new CountryManager(context).getAllPays());
this.context = context;
this.countries = countries;
}
#Override
public int getCount() {
return countries.size();
}
#Override
public Country getItem(int i) {
return countries.get(i);
}
public int getPosition(Country item) {
return countries.indexOf(item);
}
#Override
public long getItemId(int i) {
return i;
}
public int indexOf( String code) {
for (int index = 0, count = getCount(); index < count; index++)
{
if (getItem(index).getCode().equals(code)) {
return index;
}
}
return -1;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.country_list_item, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.txtViewCountryName);
//ImageView imageView = (ImageView) rowView.findViewById(R.id.imgViewFlag);
String prefix = getItem(position).getPrefix();
String code = getItem(position).getCode();
String label = getItem(position).getLabel();
textView.setText(" "+code);
String buttonID = "drawable/" + code.toLowerCase();
int resID = context.getResources().getIdentifier(buttonID, "id", context.getPackageName());
Drawable img = context.getResources().getDrawable( resID);
textView.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null);
return rowView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.country_list_item, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.txtViewCountryName);
//ImageView imageView = (ImageView) rowView.findViewById(R.id.imgViewFlag);
String prefix = getItem(position).getPrefix();
String code = getItem(position).getCode();
String label = getItem(position).getLabel();
textView.setText(" "+code);
textView.setGravity(Gravity.LEFT);
String buttonID = "drawable/" + code.toLowerCase();
int resID = context.getResources().getIdentifier(buttonID, "id", context.getPackageName());
Drawable img = context.getResources().getDrawable( resID);
textView.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null);
return rowView;
}
private String GetCountryZipCode(String ssid){
Locale loc = new Locale("", ssid);
return loc.getDisplayCountry().trim();
}
}
I expect to get countries for each user from SQLite
The problem is that the adapter is a null pointer. You have to call setContentView(<YourView>); at the beginning before calling setAdapter.
Related
I have created a recycler view and want to put two lists in it.
The first list is just a string that gets changed into fonts, which I have implemented in the onBindView method.
The second list is the cursor which includes the favorite fonts of the users.
I followed this answer on SO but I don't have any idea how I'm going to modify the getItemViewType() method so that I can get to know which list type is currently calling for view.
My adapter code
here data is the class that contains the list of fonts
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_TEXTVIEW = 0;
private final int VIEW_TYPE_ITEM_1 = 1;
private int total_no_of_row;
private Context context;
private String str;
private Cursor cursor;
private final LayoutInflater inflater;
public MyAdapter(Context context, int total_no_of_row, String str , Cursor cursor) {
this.context = context;
this.total_no_of_row = total_no_of_row;
this.str = str;
this.cursor = cursor;
inflater = LayoutInflater.from(context);
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == VIEW_TYPE_TEXTVIEW) {
View view = inflater.inflate(R.layout.row_layout, parent, false);
return new Item1Holder(view);
}
else if (viewType == VIEW_TYPE_ITEM_1){
View view = inflater.inflate(R.layout.row_layout, parent, false);
return new Item2Holder(view);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if(holder instanceof Item1Holder){
data d = new data();
cursor.moveToPosition(position);
Log.d("this2",cursor.getInt(1)+"");
String temp = d.Convert(str, cursor.getInt(1));
((Item1Holder)holder).textView.setText(temp);
((Item1Holder)holder).rowNumber.setText("⚫");
((Item1Holder)holder).fav.setImageResource(R.drawable.ic_baseline_favorite_24);
}else if(holder instanceof Item2Holder){
data d = new data();
String temp = d.Convert(str, position);
((Item2Holder)holder).textView.setText(temp);
((Item2Holder)holder).rowNumber.setText((position + 1) + ".");
if (util.COPY) {
if (position == util.CURRENT_POSITION) {
((Item2Holder)holder).imageView.setBackgroundResource(R.drawable.background_when_row_clicked);
} else {
((Item2Holder)holder).imageView.setBackgroundResource(R.drawable.background_when_row_clicked_two);
}
}
}
}
#Override
public int getItemCount() {
return total_no_of_row + cursor.getCount();
}
class Item1Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView , fav;
TextView rowNumber;
public Item1Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_body);
imageView = itemView.findViewById(R.id.copy_png);
rowNumber = itemView.findViewById(R.id.row_number);
fav = itemView.findViewById(R.id.fav);
}
}
class Item2Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView , fav;
TextView rowNumber;
public Item2Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_body);
imageView = itemView.findViewById(R.id.copy_png);
rowNumber = itemView.findViewById(R.id.row_number);
fav = itemView.findViewById(R.id.fav);
}
}
}
in main activity
here temp is the string that users want to convert into the fonts
Cursor cursor = show();
myAdapter = new MyAdapter(this , 500 , temp , cursor);
recyclerView.setAdapter(myAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
I'm not a professional android developer I'm still learning the stuff. so sorry if my code is too bad to understand
You are passing null in the onCreateViewHolder() method, and not specified position in getItemViewType() method. All you have to do is, update your code. do not pass the null value in the onCreateViewHolder method. Below code, I've tried, and works perfectly. Happy coding...
private static final int CATEGORY = 1;
private static final int NAME = 2;
private Collection<CategorizedName> data;
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof Category) {
return CATEGORY;
} else if (items.get(position) instanceof Name) {
return NAME;
}
throw new RuntimeException('error');
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (viewType) {
case CATEGORY:
View categoryView = inflater.inflate(R.layout.viewholder_category, viewGroup,
false);
viewHolder = new CategoryViewHolder(categoryView);
break;
case NAME:
View nameView = inflater.inflate(R.layout.viewholder_name, viewGroup, false);
viewHolder = new NameViewHolder(nameView);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case USER:
CategoryViewHolder categoryViewHolder = (CategoryViewHolder) viewHolder;
bindCategoryViewHolder(categoryViewHolder, position);
break;
case IMAGE:
NameViewHolder nameViewHolder = (NameViewHolder) viewHolder;
bindNameViewHolder(nameViewHolder, position);
break;
}
}
Replace your getItemViewType() with this
#Override
public int getItemViewType(int position){
if(position < total_no_of_row){
return VIEW_TYPE_TEXTVIEW;
}
if(position - total_no_of_row < cursor.getCount()){
return VIEW_TYPE_ITEM_1;
}
return -1;
}
you can also refer to my answer this
Confusing at it may seem, I am confused of what is happening too. I have an application in which there is a listview that displays values and when a row is pressed, the third value of the row will display a value.
Example is: third value is 30 and when it's pressed, it should be divided by 6, so the answer should be 5.
But when I scroll in the listview, the checkbox becomes unchecked and the third value of the row goes back to its old value (30).
Is there any way to keep the checkbox from being checked and the value of the row preserved when clicked?
Here's the snippet of my code.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkmark);
TextView tv3 = (TextView)view.findViewById(R.id.tx_counter);
EditText editText = (EditText)findViewById(R.id.editText3);
String yy = editText.getText().toString().trim();
String shitts = listView.getItemAtPosition(position).toString();
try {
String[] a = shitts.split(", ");
String[] b = a[1].split("=");
String[] sep = a[0].split("=");
String betnumber = sep[1];
String betamount= b[1];
if (view != null) {
checkBox.setChecked(!checkBox.isChecked());
if(checkBox.isChecked()){
//sort number
final String sorted = betnumber.chars().sorted().mapToObj(c -> Character.valueOf((char)c).toString()).collect(Collectors.joining());
System.out.println(sorted);
//check if double digit
Boolean checker = doubleChecker(sorted);
if (checker == true){
Toast.makeText(getApplicationContext(),"DOUBLE DIGIT", LENGTH_SHORT).show();
int answer = Integer.parseInt(betamount) / 3;
tv3.setText(String.valueOf(answer));
}else{
Toast.makeText(getApplicationContext(),"NOT DOUBLE DIGIT", LENGTH_SHORT).show();
int answer;
if(yy.equals("")){
answer = Integer.parseInt(betamount) / 6;
tv3.setText(String.valueOf(answer));
}else{
answer = (Integer.parseInt(betamount) - Integer.parseInt(yy)) / 6;
tv3.setText(String.valueOf(answer));
}
}
//TODO save to array to send
}else{
//TODO mistake RETURN tv3 to old value
}
}
}catch (Exception e){
}
}
});
Here's my adapter.
class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, String>> mData;
public MyAdapter(ArrayList<HashMap<String, String>> mData2) {
this.mData = mData2;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return this.mData.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.row_layout, null);
TextView tx_number = (TextView) view.findViewById(R.id.tx_number);
TextView tx_amount = (TextView) view.findViewById(R.id.tx_amount);
TextView tx_counter = (TextView) view.findViewById(R.id.tx_counter);
String betid = mData.get(i).get("betid");
if(betid!=null){
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
tx_number.setText(betnumber);
tx_amount.setText(amountTarget);
tx_counter.setText(amountRamble);
}
return view;
}
}
Replace your adapter code with:
public class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, String>> mData;
public MyAdapter(ArrayList<HashMap<String, String>> mData2) {
this.mData = mData2;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return this.mData.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View mView = convertView;
String betid = mData.get(i).get("betid");
ViewHolder holder ;
if (mView == null) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
mView = inflater.inflate(R.layout.row_layout, null,false);
holder = new ViewHolder();
holder.tx_number = (TextView) mView.findViewById(R.id.tx_number);
holder.tx_amount = (TextView) mView.findViewById(R.id.tx_amount);
holder.tx_counter = (TextView) mView.findViewById(R.id.tx_counter);
mView.setTag(holder);
} else {
holder = (ViewHolder) mView.getTag();
}
if (betid != null) {
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
holder.tx_number.setText(betnumber);
holder.tx_amount.setText(amountTarget);
holder.tx_counter.setText(amountRamble);
}
return mView;
}
private static class ViewHolder {
TextView tx_number;
TextView tx_amount;
TextView tx_counter;
}
}
I added new code with ViewHolder.
hi friends i had tried to implement list view in the custom dialog and passing data dynamically by using JSON and searched everywhere but don't got any solution i had tried everything from past 3 days and also i don't see any wrong in my code too i had set adapter correctly i am getting this error
Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
public class Cat_comment_adap extends BaseAdapter {
String cid;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
int idddget;
private LayoutInflater inflater;
private List<CurrentList> catlist;
private PopupWindow commentWindow;
ArrayList<CurrentList> commentlist = new ArrayList<CurrentList>();
Activity activity;
public Cat_comment_adap(Activity activity, List<CurrentList> catlist) {
this.activity = activity;
this.catlist = catlist;
}
#Override
public int getCount() {
return catlist.size();
}
#Override
public Object getItem(int i) {
return catlist.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.cat_row, viewGroup, false);
NetworkImageView singleimg = (NetworkImageView) view.findViewById(R.id.singleimg);
final ImageView agree = (ImageView) view.findViewById(R.id.agree);
ImageView commentbox = (ImageView) view.findViewById(R.id.commentbox);
commentbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onShowpopup(view);
Toast.makeText(activity, "Comments Button clicked", Toast.LENGTH_SHORT).show();
}
});
final CurrentList catertlist = catlist.get(i);
singleimg.setImageUrl(catertlist.getCatimg(), imageLoader);
idddget = catertlist.getCcids();
SharedPreferences eveid = activity.getSharedPreferences("loginPrefs", Context.MODE_PRIVATE);
cid = eveid.getString("userid", "");
agree.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String url = "http://sampletemplates.net/majority/api.php?action=addVote&question_id=" + idddget + "&user_id=" + cid + "&vote=1&source=android";
Log.d("Vote", "http://sampletemplates.net/majority/api.php?action=addVote&question_id=" + idddget + "&user_id=" + cid + "&vote=1&source=android");
JsonObjectRequest voting = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String votings = response.getString("status");
if (votings.equals("success")) {
agree.setImageResource(R.drawable.agreed);
Toast.makeText(activity, "Voted Successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(activity, "Already Voted", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
AppController.getInstance().addToRequestQueue(voting);
}
});
return view;
}
public void onShowpopup(View v) {
LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View popupview = layoutInflater.inflate(R.layout.current_comment_dialog, null);
ListView commentsListView = (ListView) v.findViewById(R.id.commentsListView);
// commentAdapter = new comment_adapter(activity, commentlist);
WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
commentWindow = new PopupWindow(popupview, width - 50, height - 400, true);
commentWindow.setBackgroundDrawable(activity.getResources().getDrawable(R.drawable.comment_bg));
commentWindow.setFocusable(true);
commentWindow.setOutsideTouchable(true);
commentWindow.showAtLocation(v, Gravity.BOTTOM, 0, 100);
commentsListView.setAdapter(new comment_adapter(activity,commentlist));
commentAdapter.notifyDataSetChanged();
}
Adapter class
public class comment_adapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<CurrentList> commentlist;
public comment_adapter(Activity activity, List<CurrentList> commentlist){
this.activity = activity;
this.commentlist = commentlist;
}
#Override
public int getCount() {
return commentlist.size();
}
#Override
public Object getItem(int i) {
return commentlist.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (view == null)
view = inflater.inflate(R.layout.comment_row, viewGroup, false);
TextView user_name = (TextView) view.findViewById(R.id.user_name);
TextView posttime = (TextView) view.findViewById(R.id.posttime);
TextView comtsdetails = (TextView) view.findViewById(R.id.comtsdetails);
CurrentList listofcomments = commentlist.get(i);
user_name.setText(listofcomments.getEvtusername());
posttime.setText(listofcomments.getTimetaken());
comtsdetails.setText(listofcomments.getEvcomment());
return view;
}
}
here in this class Cat_comment_adap in the method onShowpopup change
View popupview = layoutInflater.inflate(R.layout.current_comment_dialog, null);
ListView commentsListView = (ListView) v.findViewById(R.id.commentsListView);
to
View popupview = layoutInflater.inflate(R.layout.current_comment_dialog, null);
ListView commentsListView = (ListView) popupview.findViewById(R.id.commentsListView);
because your inflating listview from this layout so u have to give the name of inflated layout object there not the parameter of the method
public void onClick(View view) {
onShowpopup(view);
Toast.makeText(activity, "Comments Button clicked", Toast.LENGTH_SHORT).show();
}
Here passed view is not R.layout.cat_row as you think but it's a button that was clicked.
So just use onShowpopup(self.view) and it will work :)
or change to onClick(View clickedButton)
Im creating a custom ListPreference on the back of this example.
I've implemented it and it works. But I can only add a max of 5 item to the ListPreference. If I add 7 items they appears in the list but when I click it it does nothing, just closes the ListPref dialog and return to the pref screen
public class IconPickerPreference extends ListPreference {
private class CustomListPreferenceAdapter extends ArrayAdapter<IconItem> {
private Context context;
private List<IconItem> icons;
private int resource;
public CustomListPreferenceAdapter(Context context, int resource, List<IconItem> objects) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
this.icons = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
holder = new ViewHolder();
holder.iconName = (TextView) convertView
.findViewById(R.id.iconName);
holder.iconImage = (ImageView) convertView
.findViewById(R.id.iconImage);
holder.radioButton = (RadioButton) convertView
.findViewById(R.id.iconRadio);
holder.position = position;
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.iconName.setText(icons.get(position).name);
int identifier = context.getResources().getIdentifier(
icons.get(position).file, "drawable",
context.getPackageName());
holder.iconImage.setImageResource(identifier);
holder.radioButton.setChecked(icons.get(position).isChecked);
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ViewHolder holder = (ViewHolder) v.getTag();
for (int i = 0; i < icons.size(); i++) {
if (i == holder.position)
icons.get(i).isChecked = true;
else
icons.get(i).isChecked = false;
}
getDialog().dismiss();
}
});
return convertView;
}
}
private static class IconItem {
private String file;
private boolean isChecked;
private String name;
public IconItem(CharSequence name, CharSequence file, boolean isChecked) {
this(name.toString(), file.toString(), isChecked);
}
public IconItem(String name, String file, boolean isChecked) {
this.name = name;
this.file = file;
this.isChecked = isChecked;
}
}
private static class ViewHolder {
protected ImageView iconImage;
protected TextView iconName;
protected int position;
protected RadioButton radioButton;
}
private Context context;
private ImageView icon;
private CharSequence[] iconFile;
private CharSequence[] iconName;
private List<IconItem> icons;
private SharedPreferences preferences;
private Resources resources;
private String selectedIconFile, defaultIconFile;
private TextView summary;
public IconPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
resources = context.getResources();
preferences = PreferenceManager.getDefaultSharedPreferences(context);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.attrs_icon, 0, 0);
try {
defaultIconFile = a.getString(R.styleable.attrs_icon_iconFile);
} finally {
a.recycle();
}
}
private String getEntry(String value) {
String[] entries = resources.getStringArray(R.array.iconName);
String[] values = resources.getStringArray(R.array.iconFile);
int index = Arrays.asList(values).indexOf(value);
return entries[index];
}
#Override
protected void onBindView(View view) {
super.onBindView(view);
selectedIconFile = preferences.getString(
resources.getString(R.string.custom_icon_key), defaultIconFile);
icon = (ImageView) view.findViewById(R.id.iconSelected);
updateIcon();
summary = (TextView) view.findViewById(R.id.summary);
summary.setText(getEntry(selectedIconFile));
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (icons != null) {
for (int i = 0; i < icons.size(); i++) {
IconItem item = icons.get(i);
if (item.isChecked) {
Editor editor = preferences.edit();
editor.putString(
resources.getString(R.string.custom_icon_key),
item.file);
editor.apply();
selectedIconFile = item.file;
updateIcon();
summary.setText(item.name);
break;
}
}
}
}
#Override
protected void onPrepareDialogBuilder(Builder builder) {
builder.setNegativeButton("Cancel", null);
builder.setPositiveButton(null, null);
iconName = getEntries();
iconFile = getEntryValues();
if (iconName == null || iconFile == null
|| iconName.length != iconFile.length) {
throw new IllegalStateException(
"ListPreference requires an entries array "
+ "and an entryValues array which are both the same length");
}
String selectedIcon = preferences.getString(
resources.getString(R.string.custom_icon_key),
resources.getString(R.string.icon_default));
icons = new ArrayList<IconItem>();
for (int i = 0; i < iconName.length; i++) {
boolean isSelected = selectedIcon.equals(iconFile[i]) ? true
: false;
IconItem item = new IconItem(iconName[i], iconFile[i], isSelected);
icons.add(item);
}
CustomListPreferenceAdapter customListPreferenceAdapter = new CustomListPreferenceAdapter(
context, R.layout.item_picker, icons);
builder.setAdapter(customListPreferenceAdapter, null);
}
private void updateIcon() {
int identifier = resources.getIdentifier(selectedIconFile, "drawable",
context.getPackageName());
icon.setImageResource(identifier);
icon.setTag(selectedIconFile);
}
String values
<string-array name="iconName">
<item>CHESTNUT</item>
<item>POMEGRANATE</item>
<item>OLD BRICK</item>
<item>FLAMINGO</item>
<item>SNUFF</item>
<item>RAZZMATAZZ</item>
<item>NEW YORK PINK</item>
</string-array>
<string-array name="iconFile">
<item>ic_chestnut</item>
<item>ic_pomegranate</item>
<item>ic_old_brick</item>
<item>ic_flamingo</item>
<item>ic_snuff</item>
<item>ic_razzmatazz</item>
<item>ic_new_york_pink</item>
</string-array>
7 ic_ pngs for the items above in drawable...
Logs not showing any index error...
Stumped :P
Any help appreciated
Thanks in advance
I think that the problem could be caused because you are saving the position in your ViewHolder, why do you do that?
Mark final the position field, and use it directly in your OnClickListener.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
...
#Override
public void onClick(View v) {
ViewHolder holder = (ViewHolder) v.getTag();
for (int i = 0; i < icons.size(); i++) {
if (i == position)
icons.get(i).isChecked = true;
else
icons.get(i).isChecked = false;
}
getDialog().dismiss();
}
premise: i'm newbie on Java and Android, and i've search a lot for this but i don't understand how implement getFilter in my code.
this is MainActivity (relevant code):
public void loadList() {
/* allProd and allSpec are ArrayList<String> */
String[] allProdString = allProd.toArray(new String[allProd.size()]);
String[] allSpecString = allSpec.toArray(new String[allSpec.size()]);
listViewAdapter = new ListViewAdapter(this, allProdString, allSpecString);
listView.setAdapter(listViewAdapter);
}
this is customAdapter:
public class ListViewAdapter extends BaseAdapter {
Activity context;
String title[];
String description[];
public ListViewAdapter(Activity context, String[] title, String[] description) {
super();
this.context = context;
this.title = title;
this.description = description;
}
public int getCount() {
return title.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtViewTitle;
TextView txtViewDescription;
}
public View getView(int position, View convertView, ViewGroup parent) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "font/Simple_Print.ttf");
ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.tabella_prodotti, null);
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.titoloProd);
holder.txtViewDescription = (TextView) convertView.findViewById(R.id.subtitoloProd);
holder.txtViewDescription.setTypeface(typeface);
holder.txtViewTitle.setTypeface(typeface);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtViewTitle.setText(title [position]);
holder.txtViewDescription.setText(description [position]);
return convertView;
}
}
how can I implement this function to have the ability to search within an array, and show the filtered results in the listview?
if you need any other info just ask! thanks
I think that your adapter should look like this. Also I would not recommend to instantiate objects inside getView() i.e typeface object
public class ListViewAdapter extends BaseAdapter {
String title[];
String description[];
ArrayList<String> filteredTitleList;
ArrayList<String> filteredDescripionList;
Typeface typeface;
LayoutInflater inflater;
public ListViewAdapter(Activity context, String[] title, String[] description) {
super();
this.context = context;
this.title = title;
this.description = description;
typeface = Typeface.createFromAsset(context.getAssets(),"font/Simple_Print.ttf");
inflater = context.getLayoutInflater();
this.filteredTitleList = new ArrayList<String>();
this.filteredDescripionList = new ArrayList<String>();
applyFilter(null);
}
public void applyFilter(String filter){
filteredTitleList.clear();
filteredDescripionList.clear();
for(int i=0; i < this.title.length; i++){
String tempTitle = title[i];
String tempDesc = description[i];
if(filter == null || filter.equals("")){
this.filteredTitleList.add(tempTitle);
this.filteredDescripionList.add(tempDesc);
}
else if(tempTitle.toLowerCase().contains(filter.toLowerCase()) || tempDesc.toLowerCase().contains(filter.toLowerCase())){
this.filteredTitleList.add(tempTitle);
this.filteredDescripionList.add(tempDesc);
}
}
this.notifyDataSetChanged();
}
public int getCount() {
return filteredTitleList.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtViewTitle;
TextView txtViewDescription;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.tabella_prodotti, null);
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.titoloProd);
holder.txtViewDescription = (TextView) convertView.findViewById(R.id.subtitoloProd);
holder.txtViewDescription.setTypeface(typeface);
holder.txtViewTitle.setTypeface(typeface);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtViewTitle.setText(this.filteredTitleList.get(position));
holder.txtViewDescription.setText(this.filteredDescriptionList.get(position));
return convertView;
}
}
I have found a solution and share with you, I added addTextChangedListener to inputSearch in MainActivity:
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
textLength = inputSearch.getText().length();
//allProd_sort and allSpec_sort are ArrayList for search
allProd_sort.clear();
allSpec_sort.clear();
String text = inputSearch.getText().toString();
//allProdString is the String get from ArrayList allProd
for (int y =0; y<allProdString.length; y++) {
//in my case the search works only if there are min 3 characters in search
if (textLength <= allProdString[y].length() && textLength >=3) {
if (Pattern.compile(Pattern.quote(text), Pattern.CASE_INSENSITIVE)
.matcher(allProdString[y]).find()) {
allProd_sort.add(allProdString[y]);
allSpec_sort.add(allSpecString[y]);
}
}
}
String[] allProdStringSort = allProd_sort.toArray(new String[allProd_sort.size()]);
String[] allSpecStringSort = allSpec_sort.toArray(new String[allSpec_sort.size()]);
listView.setAdapter(new ListViewAdapter(MainActivity.this, allProdStringSort, allSpecStringSort));
}
#Override
public void afterTextChanged(Editable editable) {
}
});