I have an inflated layout that appears when I select a GeoPoint, the inflated layout has a button on it and I can't seem to be able to click the button and have spent hours trying to figure out why and have done this to no avail. Below shows the code where the inflated layout is invoked and also the onClick for the button is shown.
public View getInfoContents(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.place_detail, null);
String pos = arg0.getSnippet(); //get index of the marker data
Button accept = (Button) v.findViewById(R.id.button3);
accept.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"HAPPY MAN", Toast.LENGTH_LONG).show();
}
});
try{
int ipos = Integer.parseInt(pos);
PlaceData data = mListPlaceData.get(ipos); //get the data by index
((TextView)v.findViewById(R.id.txtName)).setText(data.name); //show name of the place
((TextView)v.findViewById(R.id.txtHours)).setText("Hours: "+data.hours); //show hours of the place
((TextView)v.findViewById(R.id.txtCountry)).setText("Country: "+data.country); //show country of the place
((TextView)v.findViewById(R.id.txtAddress)).setText("Address: "+data.address); //show address of the place
((TextView)v.findViewById(R.id.txtPostCode)).setText("Postcode: "+ data.postcode); //show postcode of the place
}catch(Exception e){
}
return v;
}
});
}
The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned. This means that any subsequent changes to the view will not be reflected by the info window on the map. To update the info window later (for example, after an image has loaded), call showInfoWindow(). Furthermore, the info window will not respect any of the interactivity typical for a normal view such as touch or gesture events. However you can listen to a generic click event on the whole info window as described in the section below.
Source:https://developers.google.com/maps/documentation/android/infowindows
Related
Trudging my way through my introduction to Java and Android on a simple app and have run into an issue with ListView item selection. For one of my activities, I have a layout with two buttons, one of which is a "Delete" button, and a ListView of "passages" which are essentially timestamps for when a device has passed a sensor.
I have implemented the ability to click on an item to select it, which then enables the "Delete" button. A click of the "Delete" button removes the "passage" but I still end up with a selected item, which I don't want.
To implement selection, I added the following property to the ListView:
android:id="#+id/passagesListView"
android:choiceMode="singleChoice"
android:listSelector="#666666"
Selection is supported in OnCreate via a an OnItemClickListener:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_passages);
passagesViewAdapter = new PassagesViewAdapter(this, R.layout.passages_row_layout, passages);
final ListView passagesListView = (ListView) findViewById(R.id.passagesListView);
assert passagesListView != null;
final Button deleteButton = (Button) findViewById(R.id.deleteButton);
deleteButton.setEnabled(false);
buildPassageList();
passagesListView.setAdapter(passagesViewAdapter);
passagesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position,long arg3) {
Toast.makeText(ViewPassagesActivity.this, "position is " + position,
Toast.LENGTH_LONG).show();
view.setSelected(true);
passagesViewAdapter.notifyDataSetChanged();
selectedItemPos = position;
deleteButton.setEnabled(true);
}
});
}
This part works. However, there is some issue with deletion. As you can see in the comments, I have tried several methods that I found on StackOverflow that seemed to apply but, although I am able to delete the correct item from the list, I am still ending up with a selected item after the call to delete().
public void delete (View view)
{
final Button deleteButton = (Button) findViewById(R.id.deleteButton);
ListView passagesListView = (ListView) findViewById(R.id.passagesListView);
if(selectedItemPos != -1)
{
Toast.makeText(ViewPassagesActivity.this, "remove " + selectedItemPos,
Toast.LENGTH_LONG).show();
// This did not work, which is strange since it worked similarly for selection when clicked
// View itemView = passagesListView.getChildAt(selectedItemPos);
View itemView = passagesViewAdapter.getView(selectedItemPos, null, passagesListView);
itemView.setSelected(false);
// This was also recommended in various posts on StackOverflow.
// Not clear whether clearChoices applies only to checkBoxes?
// passagesListView.clearChoices();
// passagesListView.requestLayout();
passages.remove(selectedItemPos);
deleteButton.setEnabled(false);
selectedItemPos = -1;
passagesViewAdapter.notifyDataSetChanged();
}}
}
I also ran into some issues trying to track which item is selected via setSelected() and getSelectedItemPosition() and punted by just tracking the index myself. So, as I am new to this, I'm sure there is something I am not understanding about Views or maybe something else such as a misunderstanding of how selection works?
How can I clear the selection?
Thanks!
I don't know what your PassagesViewAdapter class looks like. Maybe you can try
passagesViewAdapter.remove(passages.get(selectedItemPos));
passages.remove(selectedItemPos);
deleteButton.setEnabled(false);
selectedItemPos = -1;
passagesViewAdapter.notifyDataSetChanged();
I have written an app which has a screen view containing a thumbnail that I want to expand to full screen view (with pan and zoom) when I click it.
The large view with pan an zoom works fine, but I want to return to the original view when I click the large image.
final TouchImageView imgBig = new TouchImageView(Dashboard.this);
final ImageView img = (ImageView) findViewById(R.id.graph);
final Bitmap bitmap = result.getImage();
img.setImageBitmap(bitmap);
img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBig.setImageBitmap(bitmap);
imgBig.setMaxZoom(4f);
setContentView(imgBig);
imgBig.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// What do I need to do here to return to original thumbnail screen view?
}
});
}
});
Have tried a number of things without success!
Just the original setContentView(R.layout.main) will set it back.
It might be better to have an ImageView in the layout xml and set its image and show and hide it. Otherwise you are stuck with just one view which may be limiting.
When you do a setContentView its initializing your activity with that content. So if you want to just put something on top of it you could just have a hidden view. In your layout xml code make an image view that sits on top of all the other views. Then set its visibility="gone" so its hidden.
Then in your onClick instead of calling setContentView just set the image bitmap like you do and call imgBig.setVisibility(View.Gone or View.Visible) to show or hide your big image.
Another possibility is to have 2 activities. And call startActivity to show your big image and then finish to go back to the other activity like it was.
Another possibility is to use fragments, but that probably more involved.
This is my problem:
https://youtu.be/k-N5uthYhYw
and this is my onBindViewHolder() method.
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.specName.setText(specList.get(position).getSpecName());
// Assign a tag number to later identify what radio-button
holder.specRadioBtn.setTag(new Integer(position));
/* Event listenr for longClick - we prob. won't use it, but it's here just in case */
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast.makeText(context, "Long press", Toast.LENGTH_SHORT).show();
return false;
}
});
/* Little hack to select its Radio Button when a specific row is tapped */
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Turn rowSelectedFlag to true since the user selected this row
rowSelectedFlag = true;
// When the user taps on a row select that row's radio button
holder.specRadioBtn.setChecked(true);
// I'm not sure why, but locally the interface needs to be started by pointing it
// to where it should drive the data (to send the params)
tempInterface = new AdminUserSpecialty();
// Call the interface to send the data (row spec-name and id) back to AdminUserSpecialty
tempInterface.activateSpecSelect(specList.get(position).getSpecName().toString(),
specList.get(position).getSpecId().toString(), rowSelectedFlag);
int clickedPos = ((Integer) holder.specRadioBtn.getTag());
// Check if the radio button is already selected
if (holder.specRadioBtn.isChecked()) {
if (lastCheckedBtn != null) {
// Don't deselect if user taps on the same row several times
if (lastCheckedBtn == holder.specRadioBtn) {
// do nothing
}
// Otherwise do deselect the previously selected radio button
else {
lastCheckedBtn.setChecked(false);
}
}
lastCheckedBtn = holder.specRadioBtn;
lastCheckedPos = clickedPos;
}
// If radio is not checked set the lastCheckedBtn to null (reset counter)
else {
lastCheckedBtn = null;
}
}
});
/* ----------------------------------------------------------------------*/
}
I can't seem to preserve my radio-button selection on RecyclerView scroll. On scroll the selection becomes erratic and random. I understand that one of RecyclerView's features is to recycle rows as they leave the screen, but what do I need to do to keep my selection? Thanks much.
I know that this was answered already but if some of you are still looking for an easier answer and your application does not rely on the RecyclerView view recycling feature much (for example if you have a fixed size list of items...) you can always set your recycler view cache view size. That way it would not recycler your views hence it would not recycler the views and you will avoid copy selected values to another views...
yourRecyclerView..setItemViewCacheSize(yourItemList.size());
Save the checked / unchecked status of the radio button (you should use checkbox instead if you want to allow the user to select multiple items) to your model (i.e. your items in the list should have a field for this) when the onClick event happens. When you bind the ViewHolder, make sure you set checkbox's value to whatever you saved in your model.
It's happen because of the Recycling mechanism
(PS: its the same for the ListView or RecyclerView).
To fix that:
1) Add a booelan variable to your model to save the state of the RadioButton
2) Update your RadioButton state in onBindViewHolder() method from this boolean in the model.
3) Add setOnCheckedChangeListener() to your RadioButton to listen to his state (checked/unchecked) and to update the boolean in your model when the state changes.
I need to implement a kind of Slide to Delete inside my ListView but what I want is not to slide the row but when the user clicks a button inside the row the delete button should show up. Is it possible? I've already implemented the Button and I know when the user press it but I pretty much have no idea on how to implement the delete button slide in effect from the right of the row.
Can someone give me an Idea on how to start?
If you don't want Swipe-to-delete, then the implementation is pretty simple.
Basically you are gonna show/hide that button on button click.
Since Android ListView reuses the Views, if you show/hide the button of a View of ListItem in onItemClick(), then when the list is scrolled the state will be lost and will result in incorrect behavior.
So we need to maintain this selection state in the Adapter's modal class. Just add a field like selected in the modal class. For instance, if you are showing list of Contact objects, then your modal class will be all like,
class Contact {
private String name;
private String number;
private boolean selected;
..........
}
from what I've understand; you need to implement lets say an edit button, then when user clicks on it, it will disappear and another button called delete will popup instead of it on the same position.
here is a possible approach to achieve that:
in your list_view_adapter.xml:
1-create a frame layout contain both of the buttons on top of each other.
2-default state of delete button is GONE -> android:visibility="gone"
3-when edit is pressed delete button will be visible and you will programmatically set Edit visibility to GONE
4-set your delete button:
#Override
public View getView(final int pos, View convertView, ViewGroup parent) {
View v = convertView;
// Some other things...
Button delete = (Button) v.findViewById(R.id.delete);
delete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// After you delete the object from Parse database here,
notifyDataSetChanged();
}
}
I'm trying to set a header and footer in my list view that are clickable buttons. The problem is that the OnClickListener isn't responding to anything and I can't figure out what I'm doing wrong.
$ View header = getLayoutInflater().inflate(R.layout.header_layout, null, true);
getListView().addHeaderView(header);
myAdapter = new myAdapter(this);
header.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do what I want when i click it
}
});
Update
The best solution I ultimately came up with was adding a separate button to the header layout, and then doing it like this:
View header = getLayoutInflater().inflate(R.layout.header_layout, null);
Button headerButton = (Button)header.findViewById(R.id.header_button);
getListView().addHeaderView(header);
headerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// My Click Stuff
}
});
You need to handle the click in the ListView's onItemClick. Simply check if that's the first or last item in the adapter and handle the clicks that way. You need to treat it as an item in the ListView.
I see a few issues:
when inflating the header, use getListView() as the second parameter (root, where you have null now)l
should the header be a View or a ViewGroup? I've ended up using ViewGroup in these situations.
finally -- perhaps you should be setting the click listener on the button in the header instead of the header itself?
There is a way more easier solution:
Just set a "OnClickListener" to the applied View:
View view = inflater.inflate(R.layout.xxx, null);
view.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
//do something
}
});
Very easy thing which solved it!
Example with a footer:
mYourListView.addFooterView(footer, null, true);
Then in the OnItemClickListener you can check:
#Override
public void onItemClick(AdapterView<?> parent,
View view, final int position, final long id) {
if (id != -1) {
// do whatever you do with list items
} else {
// do what you need after the footer been clicked
}
(If you need to handle and the header and the footer click, check position - 0 for the header and [adapter.getCount() - 1] for the footer)
This approach will provide the same visual effect while footer click as if the list item been clicked. (But if you do not need that effect just add OnClickListener to the footer and it will intercept all footer clicks)
i think the listview and buttons are fighting for focus and your listview is winning.
you'll have to use a onTouchListener for the buttons.
There is one more alternative and its to set the following on the footer. There is another method overload created but it did not come up in the docs, i had to check online documentation:
mylistView.addFooterView(footerView, null, false);
where false tells the footer its not selectable. I tested this myself and the buttons inside the footer respond to touches now. I hope this an acceptable answer.
What worked for me:
When inflating the header view, before adding it to the listview, I then used that view to get the subview and add a click listener on it
myHeaderView.findViewById(R.id.myButton).setOnClickListener(new OnClickListener() { ... } );
also, when I added it to the listView, I used the overloaded constructor with the third variable set to true
mListView.addHeaderView(myHeaderView, null, true);