What I am trying to do is access an ArrayList that is in my main activity from a customer adapter for a listview.
I have a listview that I am making clickable, which I have done within the customer adapter(where the onclick resides). When the user clicks it they will enter a caption(text) which will update an arraylist(string) in the main activity.
I have read a few other questions about this topic but I'm lost on how to make this work.
I didn't see the need to post a code snippet because it's just a basic arraylist(string) and a custom adapter for a listview. If code is needed I can post though. Thanks!
Here part of the adapter code:
public class PhotoAdapter extends ArrayAdapter<Photo> {
private final ArrayList<Photo> objects;
public PhotoAdapter(Context context, int textViewResourceId,
ArrayList<Photo> objects) {
super(context, textViewResourceId, objects);
this.objects = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Photo i = objects.get(position);
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listview_row, null);
v.setClickable(true);
v.setFocusable(true);
}
Here is come code from the main activity
public ArrayList<Photo> m_photos = new ArrayList<Photo>();
public ArrayList<String> m_photo_captions = new ArrayList<String>();
private PhotoAdapter m_adapter;
this.list1 = (ListView) findViewById(R.id.lstPhotos);
m_adapter = new PhotoAdapter(this, R.layout.listview_row, m_photos);
LayoutInflater infalter = getLayoutInflater();
list1.setAdapter(m_adapter);
if (Intent.ACTION_SEND_MULTIPLE.equals(action)
&& intentGallery.hasExtra(Intent.EXTRA_STREAM)) {
ArrayList<Parcelable> list = intentGallery
.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
for (Parcelable p : list) {
Uri uri = (Uri) p;
imagePath = getPath(uri);
m_photos.add(new Photo(imagePath, ""));
m_photo_locations.add(imagePath);
m_photo_captions.add("");
m_adapter.notifyDataSetChanged();
}
}
onclick listener
list1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Do whatever you want with m_photo_captions here
Log.v("listview", "listview item clicked");
appErrorAlert("test", "test");
}
});
You can define the ArrayList you want to access as a global instance variable, that way you can access it from inside your custom adapter.
It'll also be helpful if you provided a code snippet for your problem.
Now that you have posted your code, I would suggest a different approach than Mohamed A. Karim's.
You are trying to set a simple OnClickListener on the entire row in your Adapter but access members of your Activity. Why not just set an OnItemClickListener in your ListView which already has access to the List that you want?
list1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Do whatever you want with m_photo_captions here
}
});
Next remove everything that will intercept the touch event before it reaches your ListView. You can also make your getView() a little smaller and faster, like this:
public class PhotoAdapter extends ArrayAdapter<Photo> {
LayoutInflater mInflater;
public PhotoAdapter(Context context, int textViewResourceId,
ArrayList<Photo> objects) {
super(context, textViewResourceId, objects);
mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Photo i = get(position);
View v = convertView;
if (v == null) {
v = mInflater.inflate(R.layout.listview_row, null);
// Initialize your ViewHolder here!
}
// Update your TextViews, ImageViews, etc here
...
}
}
Hope that helps!
Related
Am building an app for exploring files and am using the android native resource layout for data population called android.R.simple_list_item_1, i have tried going through the methods of a listview to see if i can add a drawable to the left of each item in my list but didn't manage. So the only way i get to access a view from a listview is on event OnItemClick where the view tapped is passed as parameter to the method and then i can format it this way for the drawable
public class MainActivity extends AppCompatActivity {
//Define a listview for holding the data mined from storage
public ListView mydata;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Define the listview
mydata=findViewById(R.id.data);
mydata.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
//Cast view to TextView at position
TextView r=(TextView)view;
//get the drawable and set to textview
Drawable mydraw= ResourcesCompat.getDrawable(getResources(),R.drawable.ic_baseline_file_copy_24,null);
r.setCompoundDrawables(mydraw,null,null,null);
}
}
}
Is there in which i can get all the views in the listview, create a loop, iterate through all of them and cast to TextView array and then set my drawable to the TextView(s)?
final static class YourItemClass {
...
}
final static class ViewHolder {
TextView mTextView;
private ViewHolder(#NonNull final View simpleListItem1) {
if (!(simpleListItem1 instanceof TextView)) throw new IllegalArgumentException("TextView was expected as root of Layout");
this.mTextView = (TextView)simpleListItem1;
}
}
final class CustomArrayAdapter extends ArrayAdapter<YourItemClass> {
private final Drawable mDrawable;
private final LayoutInflater mLayoutInflater;
public CustomArrayAdapter(#NonNull final Context context, #NonNull final List<YourItemClass> objects) {
super(context, resource, objects);
this.mDrawable = ResourcesCompat.getDrawable(getResources(),R.drawable.ic_baseline_file_copy_24,null);
this.mLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull final ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = this.mLayoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
final YourItemClass cYourItemClassAtSpecificPosition = this.getItem(position);
holder.mTextView.setCompoundDrawables(this.mDrawable, null, null, null);
return convertView;
}
}
Then from your Activity/Fragment:
private void setItemsToListView(#NonNull final List<YourItemClass> items) {
mListView.setAdapter(new CustomArrayAdapter(getActivity(), items));
}
This code will run "setCompoundDrawables()" for each row displayed in the ListView.
Problem - when I click on confirm button item do not disappear from the list and after touch on the listview again item is removed from the list. Why this happening please give me solution.
Overall remove method is not working in real time.
final ArrayList<orderTrialHelper> list_data;
Context context;
int resource;
ProgressDialog pd;
public orderTrial(Context context, int resource, ArrayList<orderTrialHelper> list_data) {
super(context, resource, list_data);
this.list_data = list_data;
this.context = context;
this.resource = resource;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.cust_list_trials, null, true);
}
final orderTrialHelper listdata = getItem(position);
id_no.setText(String.valueOf(listdata.getId_no()));
date.setText(listdata.getDate());
quantity.setText(String.valueOf(listdata.getQuantity()));
confirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
list_data.remove(position);
notifyDataSetChanged();
}
});
return convertView;
}
Try using recyclerview. May be that can solve your problem.
I'm trying to implement an Android app for sudoku game, and i created a customized adapter for that. i want make edit text for cells the user is allowed to modify, and textview for cell filled by the program, the number of ediTexts and textViews will be random. how do specify that in the adapter ?
This is my adapter :
public class SodukuAdapter extends BaseAdapter {
ArrayList<String> items;
static Activity mActivity;
private static LayoutInflater inflater = null;
public SodukuAdapter (Activity activity, ArrayList<String> tempTitle,) {
mActivity = activity;
items = tempTitle;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public final int getCount() {
return items.size();
}
#Override
public final Object getItem(int position) {
return items.get(position);
}
#Override
public final long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = null;
v = inflater.inflate(R.layout.item, null);
EditText et = (EditText) v.findViewById(R.id.et);
et.setText(items.get(position));
return v;
}
}
You can place both views in the same parent (e. g. parent is a RelativeLayout or a FrameLayout) so they are on top of each other. Than you simply hide one of them and show the other using setVisibility() in your getView() method of the adapter.
Of course you would need a datasource object which keeps track of whether a view should show the TextView or the EditText:
class SodokuItem {
public boolean isStatic;
public String text;
}
...
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = inflater.inflate(R.layout.item, null);
SodokuItem item = items.get(position);
EditText et = (EditText) v.findViewById(R.id.et);
TextView tv = (TextView) v.findViewById(R.id.tv);
if(item.isStatic){
et.setVisibility(GONE);
tv.setText(item.text);
}else{
tv.setVisibility(GONE);
et.setText(item.text);
}
return v;
}
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;
}
}
I have a listview of objects in my android application I have made it by using my custom ArrayAdapter and I want to get the fields of any object that now is a listItem by clicking the listItem but I haven't any idea to do this
my Content class is:
public class Content {
public String title;
public String text;
public int id;
public Date date;
}
and my ContentAdapter class:
public class ContentAdapter extends ArrayAdapter<Content> {
private ArrayList<Content> objects;
public ContentAdapter(Context context, int textViewResourceId,
ArrayList<Content> objects) {
super(context, textViewResourceId, objects);
this.objects = objects;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.content_list_item, null);
}
Content i = objects.get(position);
if (i != null) {
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView ttd = (TextView) v.findViewById(R.id.toptextdata);
TextView mt = (TextView) v.findViewById(R.id.middletext);
TextView mtd = (TextView) v.findViewById(R.id.middletextdata);
if (tt != null) {
tt.setText("title");
}
if (ttd != null) {
ttd.setText(i.title);
}
if (mt != null) {
mt.setText("text:");
}
if (mtd != null) {
mtd.setText(i.text);
}
}
return v;
}
}
now I want to get date and id by clicking a list item but not show them in the list view
should I add id and date fields to my custom arrayAdapter class to do this?
Assuming that your custom adapter holds a list of Content object, you will have to add an OnItemClickListener to your list view as below and obtain the object clicked and retrieve the attributes.
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long arg3) {
Content content = (Content ) adapterView
.getItemAtPosition(position);
//from the content object retrieve the attributes you require.
}
});