ListView for option list in AlertDialog - java

I'm trying to insert a listview inside an AlertDialog to display some options but I'm getting an error with the constructor: ArrayAdapter(this, R.layout.option_list, R.id.option, option_items);
It says cannot resolve constructor. The code is below.
private void LongClick() {
myList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View viewClicked, int position, long IDinDB) {
Cursor res = myDb.GetRow(IDinDB);
if (res.moveToFirst()) {
long idDB = res.getLong(DatabaseHelper.ROWID);
}
String[] option_items = {"Delete"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.option_list, R.id.option, option_items);
optionList.setAdapter(adapter);
optionList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ViewGroup vg = (ViewGroup) view;
TextView txt = (TextView) vg.findViewById(R.id.option);
Toast.makeText(ViewActivity.this, txt.getText().toString(), Toast.LENGTH_LONG).show();
}
});
return true;
}
});
}
Any help will be appreciated.

When you write this it means the current object instance class you write in. When you wrote new AdapterView.OnItemLongClickListener() you create a new anonymous class, so the word this inside its methods will refer to this newly created class object. ArrayAdapter needs context instance in constructor, not a AdapterView.OnItemLongClickListener. So you need to reference the context object. You can get it:
a) from method parameter viewClicked object (viewClicked.getContext())
or
b) as
ViewActivity.this as you did in onItemClick

Related

How can I use recyclerviewadapter with sqlite in android?

I have an SQLite database in android. I couldn't be able to see image data in RecyclerView. How can I see that in the activity page with a RecyclerView adapter?
I tried this but EpisodesAdapter episodesAdapter = new EpisodeAdapter(this, cursorEpisode, 0); this line is giving an error.
try {
EpisodesAdapter episodesAdapter = new EpisodeAdapter(this,cursorEpisode,0);
rvEpisodeImage.setAdapter(episodesAdapter);
Toast.makeText(this, "Succeed", Toast.LENGTH_SHORT).show();
} catch (SQLException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
This is the adapter class
public class EpisodesAdapter extends RecyclerView.Adapter<EpisodesAdapter.ViewHolder> {
private CursorAdapter mEpisodesAdapter;
private Context mEpisodesContext;
private RecyclerView.ViewHolder holder;
public EpisodesAdapter(final Context mEpisodesContext, Cursor cursor) {
this.mEpisodesContext = mEpisodesContext;
mEpisodesAdapter = new CursorAdapter(mEpisodesContext, cursor,0 ) {
#Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
// Inflate the view here
View view = LayoutInflater.from(context).inflate(R.layout.list_of_parts,viewGroup, false);
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ImageView ivParts = view.findViewById(R.id.ivParts);
String sEpisodeName = cursor.getString(cursor.getColumnIndexOrThrow("EPISODE_NAME"));
int iImgPath = (int) context.getResources().getIdentifier(sEpisodeName, "drawable", context.getPackageName());
ivParts.setImageResource(iImgPath);
}
};
}
#NonNull
#Override
public EpisodesAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mEpisodesAdapter.newView(mEpisodesContext, mEpisodesAdapter.getCursor(), parent);
holder = new ViewHolder(view);
return (ViewHolder) holder;
}
#Override
public void onBindViewHolder(#NonNull EpisodesAdapter.ViewHolder holder, int position) {
mEpisodesAdapter.getCursor().moveToPosition(position);
mEpisodesAdapter.bindView(holder.itemView,mEpisodesContext,mEpisodesAdapter.getCursor());
}
#Override
public int getItemCount() {
return mEpisodesAdapter.getCount();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
private ImageView ivParts;
public ViewHolder(#NonNull View itemView) {
super(itemView);
ivParts = itemView.findViewById(R.id.ivParts);
}
}
}
What am I missing here? What should I do to get a view in RecyclerView?
EpisodesAdapter episodesAdapter = new EpisodeAdapter(this, cursorEpisode, 0);
I would like to suggest you read the values from the cursor first and save the values in an ArrayList. Then pass the ArrayList to the adapter instead of passing the cursor.
The problem in your adapter is, you should get the same value from the cursor for every item in your RecyclerView as you are not actually iterating over the cursor when the position changes. The Cursor works as a pointer and hence you need to move to the next pointer to get the next element in your cursor. Hence I would like to suggest something like the following.
Declare a class to handle your data first.
public class Episode {
public String episodeName;
public int imagePath;
}
Then after getting the cursor from your database, iterate through the cursor and populate an ArrayList of Episode like the following.
public ArrayList<Episode> getEpisodesFromCursor(Cursor cursor, Context context) {
ArrayList<Episode> episodes = new ArrayList<Episode>();
if (cursor == null) return episodes;
cursor.moveToFirst();
do {
Episode episode = new Episode();
String episodeName = cursor.getString(cursor.getColumnIndexOrThrow("EPISODE_NAME"));
episode.episodeName = episodeName;
episode.imagePath = (int) context.getResources().getIdentifier(episodeName, "drawable", context.getPackageName());
episodes.add(episode);
} while(cursor.moveToNext());
return episodes;
}
Pass the cursor to the function above to get an ArrayList of your items. Then modify your adapter to accept the ArrayList<Episode> and then change your other functions accordingly.
Once you have passed the ArrayList, modify the bindView function accordingly to show proper image and other data.
#Override
public void bindView(View view, Context context, int position) {
ImageView ivParts = view.findViewById(R.id.ivParts);
String sEpisodeName = episodes.get(position).episodeName;
int iImgPath = (int) context.getResources().getIdentifier(sEpisodeName, "drawable", context.getPackageName());
ivParts.setImageResource(iImgPath);
}
I just have added some sample implementation and you need to change the code as per your need. I hope that helps!
Edit:
Moreover, you are getting the error as the adapter constructor is expecting different parameters. You need to modify the constructor of your adapter anyway if you are using an ArrayList as I have suggested.

Load Multiple Images in ListView

I was following a NewBoston Tutorial (https://www.youtube.com/watch?v=nOdSARCVYic&list=PL6gx4Cwl9DGBsvRxJJOzG4r4k_zLKrnxl&index=48)
He showed how to put an image into a list but he never showed how to assign a different image to every piece of text.
Here is my MainActivity.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] Jobsites = {"River Park Place", "Mayfair", "Jameson House"};
ListAdapter jobsiteAdapter = new CustomAdapter(this, Jobsites);
ListView jobsiteListView = (ListView) findViewById(R.id.jobsiteListView);
jobsiteListView.setAdapter(jobsiteAdapter);
jobsiteListView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String jobsite = String.valueOf(parent.getItemAtPosition(position));
//Toast.makeText(MainActivity.this, jobsite, Toast.LENGTH_LONG).show();
if (jobsite == "River Park Place"){
//Perform segue to the proper view where employess can sign in
//******************************************
System.out.println("*****************");
System.out.println("Attempting to segue");
System.out.println("*****************");
//******************************************
}else{
System.out.println("*****************");
System.out.println("These jobsites aren't avaliable yet!");
System.out.println("*****************");
Toast.makeText(MainActivity.this, "**These Sites aren't avaliable yet!**", Toast.LENGTH_LONG).show();
}
}
}
);
}
}
During the video we made a custom View that handles the images. Here is the code.
class CustomAdapter extends ArrayAdapter<String> {
public CustomAdapter(Context context, String[] jobsites) {
super(context,R.layout.custom_row ,jobsites);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater jobsiteInflater = LayoutInflater.from(getContext());
View customView = jobsiteInflater.inflate(R.layout.custom_row, parent, false);
String singleJobsiteItem = getItem(position);
ImageView josbiteImage = (ImageView) customView.findViewById(R.id.josbiteImage);
josbiteImage.setImageResource(R.drawable.riverparkplace);
return customView;
}
}
I have two other images that I want to add in for the bottom two items of text in the list. Right now it is just loading the SAME picture over and over again for all three rows in the list.
Let me guide you through this step by step. Before we continue, you need to understand that ArrayAdapter of your ListView populates each row with the data you specify to it. In other words, You would like to pass the image to the adapter just like you did with the Jobsites String array.
Define a simple wrapper object that contains your String (Jobsites) and the image you would like to assign to it.
public class SimpleObject {
private String jobSite;
private int imageID; // your R.drawable.image
public SimpleObject(String jobSite, int imageID) {
this.jobSite = jobSite;
this.imageID = imageID;
}
public String getJobSite() {
return jobSite;
}
public int getImageID() {
return imageID;
}
}
Initialise your SimpleObject array to be used by the adapter. In your onCreate() of the main activity, do the following:
ArrayList<SimpleObject> objectList = new ArrayList<>();
objectList.add(new SimpleObject("River Park Place", R.drawable.image1);
objectList.add(new SimpleObject("Mayfair", R.drawable.image2);
// the list goes on....
Now, change your CustomAdapter to hold the SimpleObject instead of String:
class CustomAdapter extends ArrayAdapter<SimpleObject> {
public CustomAdapter(Context context, ArrayList<SimpleObject> objectList) {
super(context,R.layout.custom_row ,objectList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater jobsiteInflater = LayoutInflater.from(getContext());
View customView = jobsiteInflater.inflate(R.layout.custom_row, parent, false);
// Get the SimpleObject
SimpleObject item = (SimpleObject) getItem(position);
String singleJobsiteItem = item.getJobSite(); // get the String
ImageView josbiteImage = (ImageView) customView.findViewById(R.id.josbiteImage);
josbiteImage.setImageResource(item.getImageID()); // get the image ID and assign it to jobsiteImage :)
return customView;
}
}
Now make sure you initialise the adapter in your main activity with the new SimpleObject list:
ListAdapter jobsiteAdapter = new CustomAdapter(this, objectList);
You need to implement baseadapter because of the images

Updating ListView On Custom ArrayAdapter

I apologize if this is similar to other threads, but I have yet to find a good solution on how to update the ListView in my custom ArrayAdapter.
I'm extending FragmentActivity in order to create a custom Dialog popup for adding / updating new List entries (which works fine), but I can't seem to get the ListView in ServerActivityArrayAdapter to update after a change is made.
Obviously, adapter.notifyDataSetChanged(); in the ServersActivity class isn't enough, but I'm stumped as to how to get my ListView to update after the Save button is clicked in the ServerDialog popup. Any help would be greatly appreciated!
public class ServersActivity extends FragmentActivity {
private List<Server> server;
private ListView lv;
private ServerActivityArrayAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server_list);
server = getServers();
lv = (ListView) findViewById(android.R.id.list);
adapter = new ServerActivityArrayAdapter(this, R.layout.server_list_item, server);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
showServerDialog(position);
}
});
}
...
private void showServerDialog(int position) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
ServerDialog serverDialog = new ServerDialog(position);
ServerDialog.newInstance();
serverDialog.show(fragmentManager, "server_dialog");
}
ServerDialog class for adding new List entries
public class ServerDialog extends DialogFragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.settings_fragment, container);
context = getActivity().getApplicationContext();
dbh = new DbHandler(context);
etName = (EditText) view.findViewById(R.id.etName);
etAddress = (EditText) view.findViewById(R.id.etAddress);
etPort = (EditText) view.findViewById(R.id.etPort);
swtchNumDoors = (Switch) view.findViewById(R.id.swtchNumDoors);
Button btnSave = (Button) view.findViewById(R.id.btnSave);
loadData();
String title = (!newServer) ? "Edit Server" : "Add A New Server " + ID;
getDialog().setTitle(title);
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
server[ID] = String.valueOf(ID);
server[SERVER_NAME] = etName.getText().toString();
server[ADDRESS] = etAddress.getText().toString();
server[PORT] = etPort.getText().toString();
if (server[ADDRESS].isEmpty() || server[PORT].isEmpty()) {
Toast.makeText(context, "Invalid Entry", Toast.LENGTH_LONG).show();
} else {
saveData();
// TODO - notify ServersActivity of change
}
}
});
return view;
}
public class ServerActivityArrayAdapter extends ArrayAdapter<Server> {
private int layout;
private String[][] values;
private int defServer;
private static LayoutInflater inflater;
ServerActivityArrayAdapter class for displaying ListView
public ServerActivityArrayAdapter(Context context, int layout, List<Server> servers) {
super(context, layout, servers);
this.layout = layout;
int i = 0;
values = new String[servers.size()][5];
for (Server server : servers) {
values[i][0] = Integer.toString(server.id);
values[i][1] = server.name;
values[i][2] = server.address;
values[i][3] = Integer.toString(server.port);
values[i][4] = Integer.toString(server.num_doors);
defServer = (server.default_server) ? i : 0;
i++;
}
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
private static class ViewHolder {
private TextView tvServerName;
private CheckBox cbDefault;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
try {
if(v == null) {
v = inflater.inflate(layout, parent, false);
holder = new ViewHolder();
holder.tvServerName = (TextView) v.findViewById(R.id.tvServerName);
holder.cbDefault = (CheckBox) v.findViewById(R.id.cbDefault);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.tvServerName.setText(values[position][1]);
holder.cbDefault.setChecked(defServer==position);
} catch (Exception e){
System.out.println(e);
}
return v;
}
You could use an interface and have a method in it maybe named updateListView().
Implement this interface in your FragmentActivity. In the implemented method, add code to update the listView.
And in the button code of your dialog, call ((Interfacename) getActivity).updateListView()
Your problem is in the implementation of the adapter. You are instantiating the ArrayAdapter with a List<Server> object (The super call) but then creating your own two dimensional array values to contain the data. You use the values array for the getView() method yet make no mention or show through code how you actually modify that data to update the adapter.
You should be calling back into the adapter to update it. EG, calling add(), remove(), etc. You only mention updating the DB which has nothing to do with updating your adapter. It's not linked in anyway to the DB. Even if you were to call into the previously mentioned mutate methods on the adapter, they wouldn't work unless you specifically override them. The default ArrayAdapter implementation will modify the List<Server> data and not the values two-dim array you created.
But if you find yourself override those mutate methods to support your values two-dim array...there's no point in subclassing the ArrayAdapter. Part of the point of the ArrayAdapter is handling all the data management for you. In such a situation you should be instead subclassing BaseAdapter.

Access main class member variable from setOnItemClickListener

I have implemented an activity with a simple ListView. In the java file, I have implemented OnItemClickListener() to respond to ListView item clicked.
public class MainActivity extends Activity
{
private String value;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.home_screen);
value = "Hello World";
final ListView listview = (ListView)findViewById(R.id.listview);
final ArrayAdapter<String> aa;
aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, ListValues);
listview.setAdapter(aa);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id)
{
// Get Item Clicked
String ItemSelected = (String)listview.getItemAtPosition(position);
// Access "value" containing "Hello World"
}
}
}
I need to access member variable value of my MainActivity class in onItemClick(). Kindly tell me how to do it.
Simply use:
MainActivity.this.value;
Or, even simpler, just as if it was a member of the OnClickListener:
value
Will also work.
you declared it globally so you can use it directly
#Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id)
{
//Get Item Clicked
String ItemSelected = (String)listview.getItemAtPosition(position);
Toast.makeText(getApplicationContext,value,Toast.LENGTH).show();
^
here
}

Where to initialize onLongClickListener

I am struggling with trying to implement an OnLongClick feature - I can't understand where to add a listener and to define the resulting method.
The implementation i have used uses an adapter - and does not have an onClickListener, but works jsut fine. can anyone suggest where/how to implement OnLongClick listener
I don't need every item in the list to perform different actions - just for anywere on the screen to pick up the long press
public class CombChange extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ListEdit(this, symbols));
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
String selectedValue = (String) getListAdapter().getItem(position);
if (lastPressed.equals(selectedValue) ){
count++;}
}
public class ListEdit extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public ListEdit(Context context, String[] values) {
super(context, R.layout.activity_comb_change, values);
this.context = context;
this.values = values;
}
#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.activity_comb_change, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.logo);
textView.setText(values[position]);
// Change icon based on name
String s = values[position];
if (s.equals("a")) {
imageView.setImageResource(R.drawable.a);
return rowView;
}
}
Try this:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
v.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
String selectedValue = (String) getListAdapter().getItem(position);
if (lastPressed.equals(selectedValue) ){
count++;}
return false;
}
});
}
It is unfortunate that a ListActivity does not have a protected onListItemLongClick() method similar to the onListItemClick() function.
Instead, you can add setOnLongClickListener() to the top-level layout item (or any View) in your adapter's getView() function.
Example:
myView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// Do something here.
return true;
}
});
Warning, the OnLongClickListener you put onto your list item may hide exposure to the onListItemClick() function you already have working for the list. If this is the case, you will also have to add setOnClickListener() to getView() and use it instead.
in your getView you can say
rowview.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View arg0) {
//Do your stuff here
return false;
}
});

Categories