I have a custom adapter where i display text and a spinner. I have tried to store the state of each spinner so as to display the same items when the activity is open again i have tried different things but i have not been successfull. Please how do i accomplish this thanks. This is the latest thing i have tried
CustomListAdapter(Context context, ArrayList<String> subjects) {
super(context, R.layout.custom_list_view, subjects);
}
#NonNull
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
View customView = layoutInflater.inflate(R.layout.custom_list_view, parent, false);
singleSubject = getItem(position);
TextView singleText = (TextView) customView.findViewById(R.id.listSubjectsMyCourses);
colorLayout = (LinearLayout)customView.findViewById(R.id.colorForSubjects);
relativeLayout = (RelativeLayout)
customView.findViewById(R.id.relativeForView);
parentLayout = (RelativeLayout)
customView.findViewById(R.id.parentLayout);
points = new ArrayList<>();
selected = new ArrayList<>();
selectedsttring = new ArrayList<>();
customView.findViewById(R.id.textViewForGrades);
tinyDB = new TinyDB(getContext());
spinnerForGradePoints = (Spinner)customView.findViewById(R.id.spinnerForGrades);
final ArrayAdapter<String> gradePointAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_dropdown_item_1line, UserCourseSelection2.userSubjectGradePoint);
spinnerForGradePoints.setAdapter(gradePointAdapter);
spinnerForGradePoints.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
selectedItempos = adapterView.getSelectedItemPosition();
String getSelectedItem = adapterView.getItemAtPosition(i).toString();
tinyDB.putInt("selected", selectedItempos);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
singleText.setText(singleSubject);
colorLayout.setBackgroundColor(UserCourseSelection2.userSubjectsListColor.get(position));
int getSelected = tinyDB.getInt("selected");
spinnerForGradePoints.setSelection(getSelected);
return customView;
}
SharedPreferences is the way if you dont want to use dependency injection like dagger or some kind of custom local cache on the application level.
For SharedPreferences in spinner check this answer:
https://stackoverflow.com/a/13431729/5577679
Related
I am using GridView in my alert dialogue with below codes.its giving me error called in title. My codes and more required information is like below.
private void showGotoPageDialog() {
final Dialog mDialog = new Dialog(getActivity());
mDialog.setContentView(R.layout.grid_dialogue);
mDialog.getWindow().setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
GridView mGridView = (GridView) mDialog.findViewById(R.id.grid_dialog);
ArrayList<String> tmp = new ArrayList<>(mPageOptions.length);
for(int i = 0; i < mPageOptions.length; i++)
{
tmp.add(mPageOptions[i].split(" ")[1]);
}
CustomAdapter adapter = new CustomAdapter(getActivity(), tmp, mPageIndx);
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, tmp);
mGridView.setAdapter(adapter);
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int item, long l) {
mDialog.dismiss();
mPageIndx = item + 1;
updateQuotesListServer();
updatePageInfo();
}
});
mDialog.show();
TextView dismiss = (TextView) mDialog.findViewById(R.id.dialog_dismiss);
dismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDialog.dismiss();
}
});
}
and Adapter like this
private class CustomAdapter extends BaseAdapter
{
private ArrayList<String> list;
private LayoutInflater inflater;
private int currentPage;
CustomAdapter(Activity activity, ArrayList<String> list, int currentPage)
{
this.list = new ArrayList<>();
this.list.addAll(list);
inflater = (LayoutInflater) activity.getSystemService(AppCompatActivity.LAYOUT_INFLATER_SERVICE);
this.currentPage = currentPage;
}
public void setCurrentPage(int currentPage)
{
this.currentPage = currentPage;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = View.inflate(getActivity(),R.layout.dialogue_item, null);
TextView txt = (TextView) view.findViewById(R.id.textview_dialogue);
txt.setText(list.get(i));
if(i == currentPage-1)
{
txt.setTextColor(Color.BLACK);
}
return view;
}
}
its giving me warning on this line
view = View.inflate(getActivity(),R.layout.dialogue_item, null);
warning is like below
Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling.
My code is working fine as expected and I am not facing any issue. I want know that What changes require for fix this and what is benefit of it ? Let me know if someone can help me for come out from this and solve my doubt.
Thanks
View adapter is built so that instead of creating a new view for each item, views that scroll off screen can be reused (they are passed in via the 2nd argument of getView). You are being warned that you should try to reuse these views instead of always inflating new ones. Change the line to
if (view == null) view = View.inflate(getActivity(),R.layout.dialogue_item, null);
Try this instead
view = View.inflate(R.layout.dialogue_item, viewGroup, null);
If not necessary, in other words if view is not null, then it is not necessary to call the following line in getView() method :
view = inflter.inflate(R.layout.spinner_rect, null);
the problem arises the same wrong source code available on the web:
https://abhiandroid.com/ui/custom-spinner-examples.html
https://demonuts.com/android-custom-spinner-image/
apply my solution for correctness
Thanks for useful answers: I had the same error but I was using view binding. Resolved using this approach.
I can get the text to set once but after it sets the app crashes and it shows an out of bounds error:
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
But i'm not sure why it is out of bounds when I have set a counter and it gets the text then increments the counter.
What I want to do is when the user writes a note on the Edit text and clicks a button this sets the text in a textview, then the user can add another note and this will go under the previous textview and so on. But tried various things and it's not working:
In my Tab I have this:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.tab3, container, false);
final EditText notes = (EditText) v.findViewById(R.id.editText);
listView=(ListView)v.findViewById(R.id.list);
int[] cross = new int[]{R.drawable.cross};
notesofrules = new ArrayList<String>();
adapter = new CustomListAdapter(this.getActivity(), notesofrules, cross);
listView=(ListView) v.findViewById(R.id.list);
Button button = (Button)v.findViewById(R.id.button3);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
notesofrules.add(counter, notes.getText().toString());
listView.setAdapter(adapter);
counter++;
notes.setText("");
}
});
return v;
}
}
CustomListAdapter:
public class CustomListAdapter extends ArrayAdapter<String> {
private final Activity context;
ArrayList<String> notes = new ArrayList<String>();
int[]imageCross;
public CustomListAdapter(Activity context, ArrayList<String> notes, int[] imageCross) {
super(context, R.layout.item,notes);
// TODO Auto-generated constructor stub
this.context=context;
this.notes = notes;
this.imageCross = imageCross;
}
public View getView(final int position, View view, ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.item, null,false);
TextView ruleNotesSet = (TextView) rowView.findViewById(R.id.textView1);
ImageView image = (ImageView) rowView.findViewById(R.id.icon);
image.setImageResource(imageCross[position]);
ruleNotesSet.setText(notes.get(position));
return rowView;
}
}
It looks like the issue is that you are using the adapter of a listview incorrectly.
You only need one instance of a listview adapter attached to a listview and it is simply the data contained in the listview adapter (e.g. List notes and int[] imageCross) that need to be updated. The adapter populates the amount of cells and their content based on the data of the list view adapter.
In your case when you try to add a second listcell the getView of the adapter attempts to populate cells and grabs data from positon = 0 and position = 1. But since only 1 element was passed into the adapter, it causes the out of bound error for position 1.
Updating data - add a method to access and modify your data in the adapter. Once you have added/removed the data you want, make sure to call adapter.notifyDataSetChanged() to refresh the cells in the listview.
Tab:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.tab3, container, false);
final EditText notes = (EditText) v.findViewById(R.id.editText);
listView=(ListView)v.findViewById(R.id.list);
int cross = R.drawable.cross;
notesofrules = new ArrayList<String>(); //initial data list
adapter = new CustomListAdapter(this.getActivity(), notesofrules, cross);
listView=(ListView) v.findViewById(R.id.list);
listView.setAdapter(adapter); //set the adapter once, only manipulate the data within
Button button = (Button)v.findViewById(R.id.button3);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
String newNote = notes.getText().toString();
adapter.addNote(newNote); //add new note to the adapter list
adapter.notifyDataSetChanged(); //very important to notify adapter and refresh the listview
notes.setText("");
}
});
return v;
}
}
Adapter:
public class CustomListAdapter extends ArrayAdapter<String> {
private final Activity context;
ArrayList<String> notes = new ArrayList<>();
int imageCross; //make this a list if you have multiple images and add similar to notes list
public CustomListAdapter(Activity context, ArrayList<String> notes, int imageCross) {
super(context, R.layout.item,notes);
// TODO Auto-generated constructor stub
this.context=context;
this.notes = notes;
this.imageCross = imageCross;
}
public View getView(final int position, View view, ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.item, null,false);
TextView ruleNotesSet = rowView.findViewById(R.id.textView1);
ImageView image = rowView.findViewById(R.id.icon);
image.setImageResource(imageCross);
ruleNotesSet.setText(notes.get(position));
return rowView;
}
public void addNote(String data) {
notes.add(data);
}
}
Im absolutely new in android studio, and Im trying to create custom listview, the problem is that it creating wrong list, as
Name
Name
------
Surname
Surname
-----
... and repeating
what I want to do is:
Name
Surname
-------
My code is:
protected void onResume() {
DBHelper db = new DBHelper(this);
ArrayList<String> names = new ArrayList<String>();
for (int i = 0; i < db.getAllContacts().size(); i++) {
names.add(db.getAllContacts().get(i).getName());
names.add(db.getAllContacts().get(i).getEmail());
}
ArrayAdapter adapter = new custom_row(this, names);
listView_allContacts.setAdapter(adapter);
super.onResume();
}
What is wrong here? Thanks in advance!
My custom_row code:
public class custom_row extends ArrayAdapter {
public custom_row(Context context, ArrayList<String> names) {
super(context, R.layout.custom_cell, names);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater peoInf = LayoutInflater.from(getContext());
View customView = peoInf.inflate(R.layout.custom_cell, parent , false);
String singlePeople = getItem(position);
TextView name_text = (TextView) customView.findViewById(R.id.name_text);
TextView email_text = (TextView) customView.findViewById(R.id.email_text);
name_text.setText(singlePeople);
email_text.setText(singlePeople);
return customView;
}
}
You need two different ArrayList one for the Names and one for the email.
try this
ArrayList<String> list;
public custom_row(Context context, ArrayList<String> names, ArrayList<String> email) {
super(context, R.layout.custom_cell, names);
list = email;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater peoInf = LayoutInflater.from(getContext());
View customView = peoInf.inflate(R.layout.custom_cell, parent , false);
String singlePeople = getItem(position);
String email = list.get(position);
TextView name_text = (TextView) customView.findViewById(R.id.name_text);
TextView email_text = (TextView) customView.findViewById(R.id.email_text);
name_text.setText(singlePeople);
email_text.setText(email);
return customView;
}
I made a listview in Android Studio. The listview has a image in every item but I don't know how to make it clickable. I did browse the internet for a solution but the hard part seems to be implementing it in my own code. I cannot figure that out.
Image in question = ex_img
-- Keep in mind when the image is clicked, it should also know its position in the list.
Thanks for reading and I hope you can help me out.
Adapter for list:
public class CustomList extends ArrayAdapter<String> {
private String[] ex_name;
private String[] ex_diff;
private String[] ex_muscle;
private String[] ex_dpr;
private Integer[] ex_img;
private Activity context;
public CustomList(Activity context, String[] ex_name, String[] ex_diff, String[] ex_muscle, String[] ex_dpr,
Integer[] ex_img) {
super(context, R.layout.row_layout, ex_name);
this.context = context;
this.ex_name = ex_name;
this.ex_muscle = ex_muscle;
this.ex_diff = ex_diff;
this.ex_dpr = ex_dpr;
this.ex_img = ex_img;
}
//LIST --> XML
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.row_layout, null, true);
TextView list_name = (TextView) listViewItem.findViewById(R.id.ex_name);
TextView list_diff = (TextView) listViewItem.findViewById(R.id.ex_diff);
TextView list_muscle = (TextView) listViewItem.findViewById(R.id.ex_muscle);
ImageView list_image = (ImageView) listViewItem.findViewById(R.id.ex_img);
TextView list_dpr = (TextView) listViewItem.findViewById(R.id.ex_dpr);
list_name.setText(ex_name[position]);
list_muscle.setText(ex_muscle[position]);
list_diff.setText(ex_diff[position]);
list_dpr.setText(ex_dpr[position]);
list_image.setImageResource(ex_img[position]);
return listViewItem;
}
}
Part from MainActivity that might be needed:
private Integer img[] = {
R.drawable.ic_favorite_white_24dp,
R.drawable.ic_location_on_white_24dp,
R.drawable.ic_update_white_24dp,
R.drawable.ic_local_dining_white_24dp,
R.drawable.ic_local_dining_white_24dp
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomList customList = new CustomList(this, name, diff, muscle, dpr, img);
listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(customList);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(),"You Clicked "+name[i],Toast.LENGTH_SHORT).show();
}
});
}
Add onClickListener to your ImageView in getView() -
list_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Here you have the position too.
});
Just make the position parameter final in getView()
I use simple_list_item_1 to show list in my app. I want to change the list so each element in list will have an image + radio button in addition to his text which taken from Const.practisesList.
This is the code now :
ListAdapter listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Const.practisesList);
final ListView tests_list = (ListView)findViewById(R.id.tests_list);
tests_list.setAdapter(listAdapter);
tests_list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
switch(position){
case Const.TEST_TYPE1_MATH:
p = practiseCreator(1)
break;
case Const.TEST_TYPE4_INSTRUCTIONS:
p = practiseCreator(4)
break;
}
}
});
What is the way to do it?
thanks
Create custom layout for your row. Implement custom adapter extended from ArrayAdapter.
private class SchemeAdapter extends ArrayAdapter<String> {
private int layout;
public SchemeAdapter(final Context context, final List<String> objects) {
//row layout id, content view id
super(context, R.layout.list_row_practice, R.id.list_row_practice_name,
objects);
layout = R.layout.list_row_practice;
}
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View row =
(convertView == null) ? getLayoutInflater().inflate(layout, parent, false) :
convertView;
if (row != null) {
final TextView name = (TextView) row.findViewById(R.id.list_row_practice_name);
//set here your text, image view src and radio button value.
}
return row;
}
}