I have numerous GeoPoints and when any GeoPoint is selected a layout is inflated above the GeoPoint giving the user details on that that location. Within the infalted layout there is an imageButton but I can't seem to click it and I don't know the reason why! Below shows the code that I have created, the code adds points of interests to the maps and also populates the inflated layout with information.
//show the place markers on map.
for (int i = 0; i<mListPlaceData.size(); i++){
PlaceData data = mListPlaceData.get(i);
data.marker = mMap.addMarker(new MarkerOptions().position(new LatLng(data.lat, data.lon)).
icon(BitmapDescriptorFactory.fromResource(R.drawable.place_mark))); //show place mark on map
data.marker.setSnippet(String.valueOf(i));//set index of the data
mMap.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.place_detail, null);
String pos = arg0.getSnippet(); //get index of the marker data
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
View.OnClickListener imageDirections = new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(TrackingServiceActivity.this,
"ImageButton is clicked!", Toast.LENGTH_SHORT).show();
}
};
imageButton = (ImageButton) v.findViewById(R.id.imageButton1);
imageButton.setOnClickListener(imageDirections);
}catch(Exception e){
}
return v;
}
});
}
Your ImageButton's declaration is wrong. Change
imageButton = (ImageButton) findViewById(R.id.imageButton1);
with
imageButton = (ImageButton) v.findViewById(R.id.imageButton1);
Related
I'm a beginner android developer, and Im working on an app for my Udacity course. I placed two buttons in the ListView item - one to open a map, and the other one to make a call. To make them work Im trying to retrieve address and phone number from the current object on the list but it`s not working, even though the map and phone app get opened, it just shows my location instead of the object location and a random phone number.
This is the code from my Adapdter class:
public class LocationAdapter extends ArrayAdapter<Location>{
private String address;
//create custom constructor for LocationAdapter
public LocationAdapter (Activity context, ArrayList<Location> locations){
super (context, 0, locations);
}
//Provide a View (ListView) for adapter
//#param position - the position of the item in the adapter
//#param convertView - the old view to reuse, if available
//#param parent - the parent view this view will be attached to
#Override
public View getView (int position, View convertView, ViewGroup parent){
View listItemView = convertView;
if (listItemView==null){
listItemView =
LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
//Get Location object from this position on the list
final Location currentLocation = getItem(position);
//Set onClickListener on Map Button and use an Intent in onClick method
to open location on map
final ImageButton mapButton = (ImageButton)
listItemView.findViewById(R.id.map_button);
mapButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String address
=Integer.toString(currentLocation.getLocationAddressString());
Intent openMap = new Intent(Intent.ACTION_VIEW);
openMap.setData(Uri.parse("geo:"+ address));
getContext().startActivity(openMap);
}
});
//Set onClickListener on Call Button and use an Intent in onClick method
to open a dialer
final ImageButton callButton = (ImageButton)
listItemView.findViewById(R.id.call_button);
callButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String number
=Integer.toString(currentLocation.getLocationPhoneNumberString());
Intent makeCall = new Intent (Intent.ACTION_DIAL);
makeCall.setData(Uri.parse("tel:"+number));
getContext().startActivity(makeCall);
}
});
//Find ImageView and set an Image of the current Location object
ImageView locationImage =(ImageView)
listItemView.findViewById(R.id.image);
locationImage.setImageResource(currentLocation.getImageResourceId());
//Find Location Name TextView and set Name of the current Location object
TextView locationName =(TextView) listItemView.findViewById(R.id.name);
locationName.setText(currentLocation.getLocationNameString());
//Find Location Description TextView and set Description of the current
Location object
TextView locationDescription = (TextView)
listItemView.findViewById(R.id.description);
locationDescription.setText(currentLocation.getLocationDescriptionString());
return listItemView;
}
}
This is the Location class code:
public class Location {
//Image associated with Location
private int mImageResourceId;
//Location name
private int mLocationNameResourceId;
//Location description
private int mLocationDescriptionResourceId;
//Location coordinates
private int mLocationAddressResourceId;
//Location phone number
private int mLocationPhoneNumberResourceId;
//Create a constructor for the Location Object
public Location (int ImageResourceId, int LocationNameResourceId, int
LocationDescriptionResourceId,
int LocationAddressResourceId, int
LocationPhoneNumberResourceId) {
mImageResourceId=ImageResourceId;
mLocationNameResourceId=LocationNameResourceId;
mLocationDescriptionResourceId=LocationDescriptionResourceId;
mLocationAddressResourceId=LocationAddressResourceId;
mLocationPhoneNumberResourceId=LocationPhoneNumberResourceId;
}
//Get image resource id
public int getImageResourceId(){
return mImageResourceId;
}
//get Location name
public int getLocationNameString(){
return mLocationNameResourceId;
}
//get Location description
public int getLocationDescriptionString(){
return mLocationDescriptionResourceId;
}
//get Location address
public int getLocationAddressString(){
return mLocationAddressResourceId;
}
//get Location phone number
public int getLocationPhoneNumberString(){
return mLocationPhoneNumberResourceId;
}
}
Solved
So, the issue turned out to be in storing LocationAddress as Integer in custom class, instead of storing it as a String.
Think this might be related to how the address URI is created on this line:
openMap.setData(Uri.parse("geo:"+ address));
Basically, this is going to output an addressUri that looks something like:
geo:123 Sesame St
But looking at the examples at https://developers.google.com/maps/documentation/urls/android-intents requires a couple changes:
1) That latitude/longitude should be set to 0,0 when using an address
2) You'll actually have to specify the ?q= part of the Uri
So I think if you change the previously mentioned line to this, it should work:
openMap.setData(Uri.parse("geo:0,0?q="+ address));
I've an Activity where I've a button which will lead to popup popup window in the same Activity. In that popup, I've multiple fields. And What I all want is to get back those values from popup to the same activity.
I've been stuck with it. Need a help :)
Related Code as follows.
This is the code in onCreate method for calling the popup.
Button button = (Button) findViewById(R.id.button9);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addProductDetails();
}
});
By calling addProductDetails() method popup gets displayed.
So in this method, the code as follows
private String addProductDetails() {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.storeproductdetails_layout, (ViewGroup) findViewById(R.id.popup_element1), false);
final PopupWindow pwindo = new PopupWindow(layout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
//get txt view from "layout" which will be added into popup window
//before it you tried to find view in activity container
/* Field Data */
product1Code = (EditText) layout.findViewById(R.id.productCodeee);
quantity1 = (EditText) layout.findViewById(R.id.quantityy);
details1 = (EditText) layout.findViewById(R.id.editText23);
orderValue1 = (EditText) layout.findViewById(R.id.editText36);
productC = String.valueOf(product1Code.getText());
qty = String.valueOf(quantity1.getText());
dts = String.valueOf(details1.getText());
orderVal = String.valueOf(orderValue1.getText());
StringBuffer sb = new StringBuffer("");
sb.append(productC+","+qty+","+dts+","+orderVal);
System.out.println("StringBuffer Value: "+sb.toString());
/* End of the field Data */
Button doneAddingProduct = (Button) layout.findViewById(R.id.doneAddingProduct);
//init your button
Button btnClosePopup = (Button) layout.findViewById(R.id.closePopup);
btnClosePopup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
pwindo.dismiss();
}
});
doneAddingProduct.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
System.out.println("Inside onclick of done adding");
Product product = new Product();
product.setProductCode(productC);
product.setQuantity(qty);
product.setDetails(dts);
product.setOrderValue(orderVal);
app.setProduct(product);
Intent intent = new Intent(OrderReturnMgmtSecondActivity.this, OrderReturnMgmtSecondActivity.class);
startActivity(intent);
}
});
//show popup window after you have done initialization of views
pwindo.showAtLocation(layout, Gravity.CENTER, 0, 0);
return sb.toString();
}
Here I was trying to do is two methods in fetching those field data back to the activity.
1) Simply trying to return the field data by concatenating as a string to who ever calls this method.
2) Creating a pojo By the name as Product(which contains the field data) and setting it in application class i.e MyApplication extends Application ( you see that code as app.setProduct(product)) and redirecting it to the same activity and trying to fetch the data from that application.
But still I'm not able to get those field data.
Any help will be appreciated :)
Create an interface
interface Listener {
void onResult(Product product);
}
Pass a listener to the method and call it
addProductDetails(Listener listener){
//...
//when finished:
listener.onResult(product);
//...
}
The caller now has to implement the interface
addProductDetails(new Listener(){
void onResult(Product product){
//do something with product
}
});
I am getting to change the visibility of one of the buttons on my viewpager but I am getting a Null Pointer Exception on this line:
save_button.setVisibility(Button.INVISIBLE);
I am wondering why that is? Is it because I am not getting the visibility property inside of my InstantiateItem() for the button? Should I? If so, how do I change the button visibility based on the fact if the page is viewed by the user or not?
What I am trying to do is: Show the save button if all the views are viewed in the viewpager. If not all the views are viewed, then hide the save button.
Here is my code:
boolean isViewed = false;
boolean buttonState= false; //unpressed, if true == pressed
int buttonValue = 0;
//Methods
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.score_viewpager);
//Specify the number of pages/views
numberOfPages = new Integer[]{1, 2, 3, 4, 5};
final Button save_button = (Button) findViewById(R.id.save);
//Initialize adapter to populate view
myAdapter = new MyAdapter(ScoreCollectionPager.this, numberOfPages, save_button);
//Search view for viewpager Id and set the adapter on the first item
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(myAdapter);
viewPager.setCurrentItem(0);
//Attach the page change listener inside the activity
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
Button save_button = (Button) findViewById(R.id.save);
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
//This method will be invoked when a new page becomes selected
#Override
public void onPageSelected(int position) {
//get position
isViewed = true;
if (isViewed && (position == numberOfPages.length)) {
save_button.setVisibility(Button.VISIBLE);
}
else {
save_button.setVisibility(Button.INVISIBLE); // Null Pointer Exception here? why?
}
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int i) {
//get state
}
});
}
private class MyAdapter extends PagerAdapter {
//fields
Button save_button;
//Constructor
public MyAdapter(Context context, numberOfPages, Button save_button) {
this.context = context;
this.numberOfPages = new ArrayList<Integer>(Arrays.asList(numberOfPages));
this.save_button = save_button;
}
//Returns total number of pages
#Override
public int getCount() {
return numberOfPages.size();
}
/**
* Create the page for the given position.
*
* #param parent The containing View in which the page will be shown.
* #param position The page position to be instantiated.
*
* #return Returns an Object representing the new page. This does not need
* to be a View, but can be some other container of the page.
*/
#Override
public Object instantiateItem(ViewGroup parent, final int position) {
//Get the inflater
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//inflate the root layout
View view = inflater.inflate(R.layout.score_collection, null);
//Save Button
save_button = (Button) view.findViewById(R.id.save);
save_button.setOnClickListener(new ViewGroup.OnClickListener() {
public void onClick(View view) {
//code for saving
}});
}
}
Move the below piece of code inside onPageSelected mehtod
Button save_button = (Button) findViewById(R.id.save);
I can see that Button instances are not the same. Make sure that you get the same object in the same layout. The first 2 buttons in your code belong to layout R.layout.score_viewpager, the last one belongs to R.layout.score_collection (in MyAdapter).
OK. It's a mess, but if you in onCreate give value to a class variable, you can access it in the other internal classes without having to call findViewById several times (expensive call).
Class var:
private final Button saveButton;
Set value in onCreate:
saveButton = (Button) findViewById(R.id.save);
I currently have a scrollview which I am adding rows to by inflating another xml layout. This is all working as it should and the row are all appearing correctly.
The issue I am having is that I am not sure how I can detect which button has been selected.
I have shown some example code for 1 on by buttons, simply put when this button is selected it toggles between 2 images. However, whenever I press the button it always automatially toggles the bottom rows button rather than the row in which the button has been selected.
Is there a way this can be implemented whilst still inflating a view to be used as a row (I do not want to dynamially create the rows, as this gets very messy)?
ScrollView scrollWeapons = (ScrollView)findViewById(R.id.scrollWeapons);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
int i = 0;
for(final Weapon w : Game.Weapons)
{
View view = new View(this);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.menuweapons_row, null);
btnSelected = (ImageButton)view.findViewById(R.id.btnSelected);
btnSelected.setId(i);
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
EquipUnequip(w.WeaponID());
}
});
}
private void EquipUnequip(int WeaponId)
{
if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected)
{
btnSelected.setImageResource(R.drawable.eqip_but_idle);
}
else
{
btnSelected.setImageResource(R.drawable.eqip_but_press);
}
}
ll.addView(view);
i++;
The onClick method of OnClickListener has a parameter v. The value of v will be the View that was clicked, i.e. the ImageButton. All you have to do now is pass the View to EquipUnequip:
...
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
EquipUnequip(w.WeaponID(), (ImageButton)v);
}
});
...
private void EquipUnequip(int WeaponId, ImageButton btnSelected) {
if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected) {
btnSelected.setImageResource(R.drawable.eqip_but_idle);
} else {
btnSelected.setImageResource(R.drawable.eqip_but_press);
}
}
PS: This part seems a bit non-sensical to me:
View view = new View(this);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.menuweapons_row, null);
Why do you create a new View just to do nothing with it and replace it with the result from the LayoutInflater?
Edit
If you really need the row of the View (and it never changes) here are 2 alternatives:
Save row in the OnClickListener
class MyOnClickListener implements OnClickListener {
private final int rowIndex;
MyOnClickListener(int rowIndex) {
this.rowIndex = rowIndex;
}
#Override
public void onClick(View v) {
// do something with rowIndex
}
}
and use it instead of your anonymus class
or simply add a final variable outside your anonymus class:
// currentRowIndex calculated by your program
// i.e. incremented in every iteration
final int rowIndex = currentRowIndex;
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// do something with rowIndex
}
});
Add the info as tag to the button (currentRowIndex would be of type int):
btnSelected.setTag(currentRowIndex); // attach Integer data to the view
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int rowIndex = (Integer)v.getTag();
// do something with rowIndex
}
});
Give the View parameter of onClick() to EquipUnequip(), cast this to ImageButton and use it. Otherwise you get the last created button.
I have this code inside my BaseAdapter Adapter:
public View getView(final int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.facebook_friends_layout, null);
TextView friendsName = (TextView)vi.findViewById(R.id.tvFacebookName); // Friends thumb
friend_image=(ImageView)vi.findViewById(R.id.ivFacebookPicture); // thumb image
song= new HashMap<String, String>();
song = data.get(position);
friendsName.setText(song.get(MyFriends.KEY_FBNAME));
//Log.i("Facebook Pangalan", ""+MyFriends.KEY_FBNAME);
FriendName = (String) friendsName.getText().toString();
FBID = song.get(MyFriends.KEY_FBID);
String fbAvatarUrl = "http://graph.facebook.com/"+ FBID +"/picture";
//Log.i("FBID", FBID);
BitmapManager.INSTANCE.loadBitmap(fbAvatarUrl, friend_image, 100,100);
Button btn=(Button)vi.findViewById(R.id.btnAdd);
if (FBID.equals(""))
{
btn.setVisibility(View.GONE);
}
else
{
btn.setVisibility(View.VISIBLE);
}
btn.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
LOCK_BASEDATA = MyFriends.LOCK_BASEDATA;
if (LOCK_BASEDATA.equals("0"))
{
//FACEBOOK FRIENDS
Log.i("", ""+FriendName);
//AddfromFacebookFriends();
}
else if (LOCK_BASEDATA.equals("1"))
{
//MY REQUEST
//((MyFriends)context).SetMyRequest();
//Log.i("LangYa", "Langya");
}
else if (LOCK_BASEDATA.equals("2"))
{
//FRIEND REQUEST
//((MyFriends)context).SetFriendRequest();
//d2papasok
AddFriendRequest();
}
}
});
return vi;
}
I am logging my friend's name whenever I click on the button. Now my problem starts when I click the button; I am not getting my desired string. It is getting the string from another row of my listview.
EDIT
Thanks, actually ive just aaded this code
public void onClick(View arg0) {
LOCK_BASEDATA = MyFriends.LOCK_BASEDATA;
if (LOCK_BASEDATA.equals("0"))
{
//Object x =btn.getTag();
//String sa = x.toString();
View parentView = (View) arg0.getParent();
String textviewtext = ((TextView) parentView.findViewById(R.id.hiddentv)).getText().toString();
//FACEBOOK FRIENDS
AddfromFacebookFriends(textviewtext);
}
else if (LOCK_BASEDATA.equals("1"))
{
I am just getting my parents View to get my desired textview and now it works. Thanks anyway
You are trying to get the FriendName using this code:
TextView friendsName = (TextView)vi.findViewById(R.id.tvFacebookName);
FriendName = (String) friendsName.getText().toString();
This is not The FriendName of the ListView item you clicked. Its the FriendName of the newly created ListView item. Because in getView(), the ListView item you get is the newly created one.
One way to solve this is:
Use tags like KunalK suggested. I am not sure if it works...i never tried it.
Or the other way is:
onButtonClicked get the Position of the ListView item you clicked, and get the respective Name from the ArrayList you are using.
Here the Position is not the position parameter in the getView(). That gives the position of the newly created ListView item again.
Use this to get the actual position of the clicked item:
int clickedItemPosition = yourListView.getPositionForView((View) yourButton.getParent());
you should go with this by setting the "FriendName" in your button's setTag property. and whenever you handle your button click event fetch your FriendName String by using getTag property of button. for e.g. something like this:
....
btn.setTag(FriendName);
btn.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
LOCK_BASEDATA = MyFriends.LOCK_BASEDATA;
if (LOCK_BASEDATA.equals("0"))
{
//FACEBOOK FRIENDS
Log.i("", ""+btn.getTag().toString());
//AddfromFacebookFriends();
}
else if (LOCK_BASEDATA.equals("1"))
{
//MY REQUEST
//((MyFriends)context).SetMyRequest();
//Log.i("LangYa", "Langya");
}
else if (LOCK_BASEDATA.equals("2"))
{
//FRIEND REQUEST
//((MyFriends)context).SetFriendRequest();
//d2papasok
AddFriendRequest();
}
}
});
....
Getting the name from the list can be accompished by using an onListItemClick method as follows (not in your adapter, but in the class with your list):
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
TextView friendsName = (TextView)v.findViewById(R.id.tvFacebookName);
FriendName = (String) friendsName.getText().toString();
}
Since this code is the onListItemClick method, the View v parameter is the view of the row you clicked. Once you have that, you search that particular row view for the TextView you want and then pull the string from that.
You had the right idea, you just put it in the wrong place.