I'm trying to show a custom toast exactly into deleted ListView item position. This is all I could do:
Adapter:
private View.OnClickListener onDeleteListener(final int position, final ViewHolder holder) {
return new View.OnClickListener() {
#Override
public void onClick(View v) {
showCustomToast(position, position);
}
};
}
public void showCustomToast(int positionX, int positionY) {
LayoutInflater inflater = LayoutInflater.from(context);
View layout = inflater.inflate(R.layout.toast_layout, null, false);
ImageView icon = (ImageView) layout.findViewById(R.id.toast_image);
TextView message = (TextView) layout.findViewById(R.id.toast_text);
LinearLayout fundoMensagem = (LinearLayout) layout.findViewById(R.id.toast_root);
message.setTextColor(Color.BLACK);
fundoMensagem.setBackgroundResource(R.color.error_colors);
message.setText("Item Deleted!");
Toast toast = new Toast(context);
toast.setDuration(toast.LENGTH_LONG);
toast.setView(layout);
toast.setGravity(positionX, positionX, positionX);
toast.show();
}
But this isn't exactly what I need because the position variable of the onDeleteListener method only get the item index and not the screen position. Someone can help me to show the custom toast at the center of each listview item?
You could use View.getLocationOnScreen() and/or getLocationInWindow() to get the absolute coordinates of a view on the screen, but I don't think a Toast is the right things to be putting there, Toasts are system level notifications, not app level, so it would be a bit of a stretch to try to force it into a position in your app. I think you would be much better served by some sort of custom view.
Related
So I have a ListView with list-items that each have different images in them. I have my code setup so that when the user clicks an image, it will show an expanded version of that particular image by using the Dialog class.
However, no matter what code I've tried, it doesn't seem like I can make the Dialog image change! Am I not able to modify layout elements from within an adapter? I could only figure out how to reference my individual list-item images by putting the relevant code within my adapter.
What needs to change, and what am I doing wrong?
Here's the applicable code in my adapter for reference:
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(LOG_TAG, "Calling ImageView OnClickListener");
int imageId = currentWord.getImageResourceId();
Dialog aD = new Dialog(mContext);
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View popupLayout = layoutInflater.inflate(R.layout.popup_image_layout, null);
ImageView popupImageView = (ImageView) popupLayout.findViewById(R.id.popup_imageView);
Glide
.with(mContext)
.load(imageId)
.apply(new RequestOptions().circleCrop())
.into(popupImageView);
aD.setContentView(R.layout.popup_image_layout);
aD.show();
}
});
Thanks for any of your help!
So I ended up figuring the answer out on my own.
Under aD.setContentView(), I should have had popupLayout as the target, which had already had R.layout.popup_image_layout assigned and inflated in the same line... By referencing the layout anew, the code wasn't actually inflating the layout, so there was nothing able to be shown.
So all that needed to be changed was: modifying aD.setContentView(R.layout.popup_image_layout) to aD.setContentView(popupLayout) and now when I click on the individual images in my ListView items, the proper image for each pops up in an expanded ImageView, which is shown by way of the Dialog class.
UPDATE:
Added some extra code in order to make sure that the Dialog is completely removed after being closed. Otherwise, it is kept in memory and the memory use continues to stack and increase indefinitely upon each subsequent Dialog being opened.
Updated code below:
Dialog aD = null;
final int imageId = currentWord.getImageResourceId();
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View popupLayout = layoutInflater.inflate(R.layout.popup_image_layout, null);
final ImageView popupImageView = (ImageView) popupLayout.findViewById(R.id.popup_imageView);
if (aD == null) {
aD = new Dialog(mContext);
aD.getWindow().setBackgroundDrawableResource(R.color.transparent);
}
Log.i(LOG_TAG, "Calling ImageView OnClickListener");
Glide
.with(mContext)
.load(imageId)
.apply(new RequestOptions().circleCrop())
.into(popupImageView);
aD.setContentView(popupLayout);
aD.show();
popupLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
aD.dismiss();
aD = null;
}
});
}
});
I am developing a music playing app but I've been stuck with fixing a bug for the last two days. Here is a screenshot of the app. Basically the user can add a new view, name it however he wishes and choose a mp3 file to link to that view.
As you can see Every view has a text that a little play icon. This icon switches to a pause icon while the audio is playing. Here you can see the pause icon.
Issue 1:
When the user starts a sound and then click on another square, the previous sound stops as it should and the new sound begins, but the old square's icon stays the pause icon, and so on the screen eventally many squares will have the pause icon while not actually playing sound.
Issue 2: Let's say that the user clicks the absolute first square, which in the arrayList corresponds to position 0. Then the user scrolls down to the point that the square he clicked is no longer visible. When the user scrolls up again the square he clicked on will have the play icon set, while playing sound. I figured that's because in my GridAdapter i set every newly recicled view to have the play icon and I can't figure out how to set an if statement. How should the adapter know wether the box is playing a sound?
Many thanks and love.
GridItemAdapter.java:
public class GridItemAdapter extends ArrayAdapter<GridItem> {
private static final String LOG_TAG = GridItemAdapter.class.getSimpleName();
public GridItemAdapter(Activity context, ArrayList<GridItem> gridItems) {
// Here, we initialize the ArrayAdapter's internal storage for the context and the list.
// the second argument is used when the ArrayAdapter is populating a single TextView.
// Because this is a custom adapter for two TextViews and an ImageView, the adapter is not
// going to use this second argument, so it can be any value. Here, we used 0.
super(context, 0, gridItems);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Check if the existing view is being reused, otherwise inflate the view
View gridItemView = convertView;
if(gridItemView == null) {
gridItemView = LayoutInflater.from(getContext()).inflate(
R.layout.grid_item, parent, false);
}
// Get the {#link AndroidFlavor} object located at this position in the list
GridItem currentGridItem = getItem(position);
// Find the TextView in the list_item.xml layout with the ID version_name
TextView nameTextView = (TextView) gridItemView.findViewById(R.id.text_1);
// set this text on the name TextView
nameTextView.setText(currentGridItem.getSoundName());
ImageView playIcon = (ImageView) gridItemView.findViewById(R.id.image_1);
playIcon.setImageResource(R.drawable.play_ic);
// Return the whole list item layout (containing 2 TextViews and an ImageView)
// so that it can be shown in the ListView
return gridItemView;
}
}
MainActivity.java snippets of interest :
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
/*
if (lastPosition != -1) {
Log.v(TAG3, "Inisde if block, lastposition = " + lastPosition);
// Whatever position you're looking for
int firstPosition = gridView.getFirstVisiblePosition();
int wantedChild = lastPosition - firstPosition;
View wantedView = gridView.getChildAt(wantedChild);
Log.v(TAG3, "lastRow initiated, lastrow = " + wantedView);
ImageView lastIc = (ImageView) wantedView.findViewById(R.id.image_1);
lastIc.setImageResource(R.drawable.play_ic);
}
*/
togglePlayback(i, view);
lastPosition = i;
Log.v(TAG3, "outside if block, lastPosition = " + lastPosition);
}
});
public void togglePlayback(int i, View v){
final View view = v;
if(!isPlaying) {
releaseMediaPlayer();
ImageView playIc = (ImageView) view.findViewById(R.id.image_1);
playIc.setImageResource(R.drawable.pause_ic);
GridItem word = gridItems.get(i);
try {
mMediaPlayer = MediaPlayer.create(MainActivity.this, Uri.parse(word.getSoundPath()));
}catch (IllegalArgumentException e){
e.printStackTrace();
}
mMediaPlayer.start();
isPlaying = true;
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
releaseMediaPlayer();
ImageView playIc = (ImageView) view.findViewById(R.id.image_1);
playIc.setImageResource(R.drawable.play_ic);
isPlaying = false;
}
});
}else{
releaseMediaPlayer();
ImageView playIc = (ImageView) view.findViewById(R.id.image_1);
playIc.setImageResource(R.drawable.play_ic);
isPlaying = false;
}
}
Here is a simple way to achieve it(I have not gone through your code since the snippet was not provided yet, the variables used below are self-explanatory):
First add a flag say isPlaying in the model class of an item in gridview
Now in getView method, add below code
if(itemList.get(index).isPlaying) {
//set the icon to pause one
} else {
//set the icon to playing one
}
Now, in view's click listener, add this
if(itemList.get(index).isPlaying) {
// write the code to pause the current song
} else {
// pause your <previousIndex> song
// play <index> item
itemList.get(index).isPlaying = true;
itemList.get(previousIndex).isPlaying = false;
previousIndex = index;
notifyDataSetChanged();
}
I have just written the basic logic, you need to write your code regarding playing/pause of your songs.
Hope this helps you.
I have created a custom arrayadapter for my listview. It has a player name and the score, I also have a add button on the cell, when that button is clicked I want a popup screen to appear, Here is where the user can add the score of the player. This popup window has 6 buttons "+1", "+2" "+10" ..etc and a done button. When the done button is clicked the score gets updated.
I am handling the add button click event on my customArraryAdapter class, so I have to create the popup here as well. I have searched and tried to do this with no success.
What I tried so far:
I have a View = convertView and a viewHolder = holder The problem is I'm not so sure what to pass as the parameter to create a popup. The code below is myCustomArrayAdapter class. I have also read popups cant handle touch events, but some are saying it can. Since my popup has a lot of buttons maybe this might be a great solution.
This is in #Override
public View getView(final int position, View convertView, ViewGroup parent) Method in CustomArrayAdapter Class
//Handle add button click
holder.add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
addScores(convertView);
//list gets updated
notifyDataSetChanged();
}
});
My addScores method looks like this
private void addScores(View v){
PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)v.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)v.findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
pw.setBackgroundDrawable(new BitmapDrawable());
pw.setOutsideTouchable(true);
pw.showAsDropDown(btnSelectWeight);
}
You may pass View that will be displayed in popup the same way you do.
Consider this:
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)v.findViewById(R.id.linlay_weight_popup));
Your weight_popup layout should contain 6 buttons, which would have onClick there you update scores.
Something like:
Button btn1 = (Button)layout.findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//update your score here.
}
});
//other buttons..
pw = new PopupWindow(layout, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
I have a listview and each item has a title, some info, and a couple ImageViews I'm using as edit/delete buttons. I don't want to show these "buttons" unless the user selects the row. I can make the "buttons" invisible using:
DeleteButton.setVisibility(View.INVISIBLE);
EditButton.setVisibility(View.INVISIBLE);
in my BindView.
I can make the buttons visible in an onListItemClick:
ImageView DeleteButton = (ImageView) v.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) v.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.VISIBLE);
EditButton.setVisibility(View.VISIBLE);
What I can't do is make the "buttons" invisible when selecting another item or scrolling away.
The closest I found was to do a loop through the listitems in the current view and set them all to invisible before making the selected one visible:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
\\loop through all the items and set them back to invisible
for (int i=0;i<=l.getLastVisiblePosition();i++){
View vChild = l.getChildAt(i);
ImageView DeleteButton = (ImageView) vChild.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) vChild.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.INVISIBLE);
EditButton.setVisibility(View.INVISIBLE);
}
\\set the selected one visible
ImageView DeleteButton = (ImageView) v.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) v.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.VISIBLE);
EditButton.setVisibility(View.VISIBLE);
}
As you can guess...this approach only works if you have a few items.
I thought about adding a field to the SQLite database my list is using to keep track of the button visibility (similar to what you do for checkboxes) but that seemed silly. Please tell me there's another way.
Another way to do this would be to have an int field in your class that will remember the current position:
private int current = -1;
then in the onItemCLick() method use that field to hide/show your views:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// if it is the first click ignore this part
if (current != -1) {
View last = l.getChildAt(current); // the last one clicked
last.findViewById(R.id.button1).setVisibility(View.GONE); // kill it
}
v.findViewById(R.id.button1).setVisibility(View.VISIBLE);
current = position; // remember the new clicked position
}
If you want the views to be gone also when you scroll the list and those views aren't visible then in the bindView() method add the lines that hide the views:
//...
ImageView DeleteButton = (ImageView) view.findViewById(R.id.button_delete); // view is the view that you get as a parameter
ImageView EditButton = (ImageView) view.findViewById(R.id.button_edit);
DeleteButton.setVisibility(View.INVISIBLE);
EditButton.setVisibility(View.INVISIBLE);
//...
When the use scrolls the list all the views will have the Buttons visibility set to GONE and the onItemCLick() logic will work only for visible views.
I dont know if i understand your question correct but make the definitions of the ImageViews
ImageView DeleteButton = (ImageView) v.findViewById(R.id.button_delete);
ImageView EditButton = (ImageView) v.findViewById(R.id.button_edit);
one time at onCreate() and not every time again! Dont know if this solves your problem but try it.
Edit:
if(tempEditButton != null && tempDeleteButton != null){
tempDeleteButton.setVisibility(View.INVISIBLE);
tempEditButton.setVisibility(View.INVISIBLE);
}
EditButton.setVisibility(View.VISIBLE);
DeleteButton.setVisibility(View.VISIBLE);
tempEditButton = EditButton;
tempDeleteButton = DeleteButton;
This is an old question but I think I can still answer it. I solved this problem by creating a public static method which can be called from anywhere:
public static void hideOptions(Activity activity){
for (int i = 0; i< listviewSize; i++) {
Listview x = (Listview ) activity.findViewById(R.id.contactRecyclerView);
x.getChildAt(i).findViewById(R.id.myView).setVisibility(View.GONE);
}
}
You can then call this method whenever you want to hide your view
I want to show a simple text view on map view pushpin.on click of that pushpin i want to show the detail info.
when user taps on specific point i want to show name of that point..these name I'm storing in POJO class and i want to retrieve from that,now in my code I'm successfully getting names but only problem is names are not displaying on that particulate tap point.
Please Help...
here is my code....
#Override
public boolean onTap(GeoPoint p, MapView mapView) {
str.
final PopupWindow popupWindow;
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.popup, (ViewGroup) findViewById(R.id.rootId));
TextView text = (TextView)layout.findViewById(R.id.nameTextView);
text.setText("Lake Name");
text.setBackgroundColor(Color.BLACK);
popupWindow=new PopupWindow(layout);
popupWindow.setTouchable(true);
popupWindow.setWidth(LayoutParams.WRAP_CONTENT);
popupWindow.setHeight(LayoutParams.WRAP_CONTENT);
popupWindow.showAtLocation(layout,Gravity.CENTER_HORIZONTAL,10,0);
builder=new AlertDialog.Builder(DummyLocationActivity.this);
text.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
LayoutInflater inflater=LayoutInflater.from(DummyLocationActivity.this);
View desc= inflater.inflate(R.layout.description,(ViewGroup) findViewById(R.id.root));
builder.setView(desc);
builder.show();
}
});
return true;
}
OnTap(int position) you can get the particular item on tap by using the position .