I want to customize my ExpandableList. My issue is that I need a button and expandable list on single activity. Can I achieve that? I have seen all the examples but all extends ExpandableListActivity not the Activity in which I can put all the widgets in one activity.
Any help would be appreciated.
According to the documentation this task should not be too hard.
the first thing that you will have to do is create a new xml file to hold your custom layout. The file should be saved in your res/layout folder and be named something like "my_custom_expandable_list_view_layout.xml", it should look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ExpandableListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<Button android:id="#id/my_button_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Click Me"/>
</LinearLayout>
The import part of that layout file is that you include an "ExpandableListView" and give it the id of "android"list".
The next thing that you will need to do is let your activity know that you are using a custom layout by calling setContentView() in your activities onCreate(). The call should look something like this
setContentView(R.layout.my_custom_expandable_list_view_layout);
At this point you should be able to run you program and see a large button at the bottom of the screen. In order to do something with this button you will need to access it via a call to findViewById() in your Activity like this
Button myButton = (Button)findViewById(R.id.my_button_id);
Once you have that myButton object you can add a click listener or whatever else you would like to do. You can pretty much add anything else you want by just adding new things to the layout file.
Related
Can I add Custom Control as Marker to OSMBONUSPACK?
I create some Buttons and image in Android xml file Named MyMarkerItem.xml
I would like something like MyMarker.setDesign(R.layout.MyMarkerItem);
Thanks
OK, I understand that you want the marker icon itself to be not a simple bitmap, but a layout.
What you can do is to use the marker infowindow "instead" of the marker icon.
First of all, create a new class CustomInfoWindow which inherits from MarkerInfoWindow - the default InfoWindow for Markers, and uses your own layout:
public class CustomInfoWindow extends MarkerInfoWindow {
public CustomInfoWindow(MapView mapView) {
super(my_own_layout, mapView);
}
}
CustomInfoWindow myCustomInfoWindow = new CustomInfoWindow(mapView);
Then, just after creating your Marker, do that:
Set a marker icon as a 1x1 pixel size bitmap, fully transparent: setIcon(mySmall_InvisibleIcon)
Set the marker infowindow to your own: setInfoWindow(myCustomInfoWindow)
Set the infowindow "anchor" to the most appropriate and natural position, depending on the "look" of your layout: setInfoWindowAnchor(ANCHOR_CENTER, ANCHOR_CENTER) maybe?
Force the opening of the infowindow: showInfoWindow()
All these steps are fairly simple.
But then, I guess you expect some behaviour to happen when the user will click on your layout buttons.
So, inside your CustomInfoWindow code, you will certainly have to do some work => follow this tutorial.
Markers in Osmdroid arent actually android views and therefore it's not possible to add other components into them. They are basically just an image.
Simple and suggested solution
You can add your components to a MarkerInfoWindow which is displayed after a click, though.
marker.setInfoWindow(new MarkerInfoWindow(R.layout.MyMarkerItem, mapView));
Possible "real" soluiton
If you really need such behaviour - meaning you really need multiple buttons displayed on a map as a "marker" and give the user the opportunity to click on them - it should be possible to create your own implementation of a Marker-like class. In other words, you would have to implement your own subclass of OverlayWithIW or Overlay and override (mainly) the draw method (which should draw your buttons to a canvas) and the onSingleTapConfirmed method, where you would need to detect properly on which button user clicked and call the related action. Try to go through source of the Marker class, it's a good example.
But keep in mind: this is an advanced task. Everything related to drawing on canvas can lead to performance issues if it's not done properly. There will be edge cases you'll have to cover. There may be other problems you'll need to solve and debug. I would not suggest such a solution to a beginner.
It's August 2021 and I wanted to add an arbitrary layout as my marker item. Much as the OP is asking for here.
I tried the Simple and suggested solution of https://stackoverflow.com/a/53003664/866333:
marker.setInfoWindow(new MarkerInfoWindow(R.layout.MyMarkerItem, mapView));
I get a runtime exception when I click it:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference.
I refine my layout down to a single TextView widget for arguments sake and the error persists.
I give up on that answer and attempt the accepted one: https://stackoverflow.com/a/53216542/866333
public class CustomInfoWindow extends MarkerInfoWindow {
public CustomInfoWindow(MapView mapView) {
super(my_own_layout, mapView);
}
}
CustomInfoWindow myCustomInfoWindow = new CustomInfoWindow(mapView);
Using the same my_own_layout as before, let's call it R.layout.my_info_window
I get the same error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
I dug into the AS-reverse engineered (thanks AS) source code to discover the reason for this error is that the layout being passed to the MarkerInfoWindow super class constructor has particular id requirements.
We must have these ids in our layout: bubble_title, bubble_description, bubble_subdescription, bubble_image
Here is a minimal working example:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/bubble_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="20dp" />
<TextView
android:id="#+id/bubble_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="39dp" />
<TextView
android:id="#+id/bubble_subdescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="58dp" />
<ImageView
android:id="#+id/bubble_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/marker_cluster"
tools:layout_editor_absoluteX="145dp"
tools:layout_editor_absoluteY="76dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
That works great!
I can even attempt to customise by appending another widget:
<TextView
android:id="#+id/anothertexttestview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="look ma!"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="125dp" />
The absoluteY is ignored and superimposed on the only text I set programmatically, the title. IOW, the widget isn't purely declarative xml. I'm afraid ConstraintLayout is after my time as a front end engineer so I'll leave it to the reader to experiment from here.
I want my app to provide a function to add a button like described by Avadhani Y in How to create Button Dynamically in android?
I copied this code and the button appears when I press the +-symbol but it isn't permanent. When I close the app and open it again, the button disappears.
For a minimal working example I
created a Blank Android Application Project set up by Eclipse
added part of the method described in How to create Button Dynamically in android? to MainActivity.java (The second case with the minusbutton generates several error messages, so I left it out.):
public void onClick(View v){
switch(v.getId()){
case (R.id.plusbutton):
Button myButton = new Button(this);
myButton.setText("Add Me");
LinearLayout ll = (LinearLayout)findViewById(R.id.buttonlayout);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
break;
}
}
imported the necessary packages. Actually I'm not sure whether I chose the right one for the line with the LayoutParams - eclipse listed several packages - I chose android.view.ViewGroup.LayoutParams
changed the activity_main.xml file to the one below.
added some strings to the strings.xml file
My activity_main.xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/buttonlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.button_test.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<Button
android:id="#+id/plusbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="#string/plus" />
</LinearLayout>
The problem is that you can't save to resources such as layout files at runtime. So, your options (AFAIK) are to save the params and attributes of the Button into a db or other persistent storage then check at startup each time to recreate the Button. This would be very cumbersome, I would imagine, and very error-prone if not careful.
Another option, if there is a finite number of Buttons available to be made, is to simply create them in your xml then use the visibility attribute to change from gone/invisible to visible when needed.
Android is "stateless" - in other words, unless you "save" changes, they are discarded. What you need to do is include a way to persist any changes that you expect to survive beyond the user's immediate interaction with your app. Also, you should assume that any change might be discarded immediately afterward - in other words, don't "wait" to save changes. If the user's phone rings, your app might go to the background and get killed before onPause or onStop or onDestroy are ever called.
Look into saving a "flag" for the visibility of the button into SharedPreferences and then read the flag in onCreate or onStart or onResume. It's likely you could use any of these, but you will find that sometimes one or another works best (or one doesn't work right at all).
New to coding to Android, but I couldn't find an answer to this particular problem. Say I have the following XML layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<view class="com.example.testapp.customView"
android:id="#+id/drawView"
android:layout_height="100dp"
android:layout_width="fill_parent" />
<Button android:id="#+id/bNormal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Update" />
</LinearLayout>
I want to use this layout to create several activities, but in each activity I want to use a different customView. Eg. for one activity I would like the custom view to be customView1, the second activity I would like it to be customView2, etc.
How would I go about doing that? Right now I just have a seperate XML layout for each of my activities, and this seems awfully redundant.
You either create several layouts, or you have to add the new view programatically (by creating an object of the proper type and adding it to the parent view) rather than doing it via xml. The idea behind xml layouts is that your layout is more or less static, so the xml specifies exactly what you want. It isn't meant to be a programming language itself where things can change.
I want to have a "comments" button on my Android e-reader app that displays the number of comments currently posted inside the icon... so basically I want a comment bubble with a number inside it.
I could have multiple drawables, each being the bubble with a different number inside of it, and use a switch statement to choose which one to load each time based on the int number_of_comments field of the element being displayed. This approach seems a little wasteful though, and in any case I have a feeling there's a more elegant way to do it.
Any ideas?
You can do better. You can have a textview on top of the image view and keep updating its value everytime a new comment is added. You can define the overlap in xml like below and adjust your code logic accordingly to increase the comment count. For now I have just set up a dummy text Hello to show on top of the ImageView. You can add your comment count using the TextView's setText method.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativelayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/myImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/myImageSouce" />
<TextView
android:id="#+id/myImageViewText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/myImageView"
android:layout_alignTop="#+id/myImageView"
android:layout_alignRight="#+id/myImageView"
android:layout_alignBottom="#+id/myImageView"
android:layout_margin="1dp"
android:gravity="center"
android:text="Hello"
android:textColor="#000000" />
</RelativeLayout>
Hope this helps...
check out this 3rd party created widget
Android ViewBadger
You can use it to create the little number bubbles that you are looking for I think. This gives you the benefit of not having modify your layouts so much to achieve what you are trying to get.
Here is the sample code to apply a "badge"
View target = findViewById(R.id.target_view);
BadgeView badge = new BadgeView(this, target);
badge.setText("1");
badge.show();
I am attempting to create a program with a set of dynamically loaded layout "pages". I have the base layout created with a minimal default skeleton of the Views common to each page. For each page I was going to hard code all the views to be swapped (:facepalm). My next thought was to create a text file and put the necessary data in a well formatted design. Only then I realized that's exactly what the XML files are. So what I would like to do is create an XML file of the pages with the data exactly as it would appear in the original layout file. Then as each page is loaded (possibly unload another page), pull the XML data for that page and insert it into the current base layout structure.
My page data
<?xml version="1.0" encoding="utf-8"?>
<pageList>
<page:1>
<Button .../>
<EditText .../>
</page>
<page:2>
...
</pagelist>
The base XML layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:weightSum="1">
<LinearLayout android:id="#+id/linearLayout1"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="1.00" android:weightSum="1">
<EditText android:id="#+id/editText1" android:inputType="textMultiLine"
android:layout_width="0dp" android:layout_weight="0.30"
android:layout_height="match_parent"></EditText>
<RelativeLayout android:layout_width="0dp"
android:id="#+id/orientationLayout" android:layout_weight="0.70"
android:layout_height="match_parent">
<dynamically insert my PAGE here>
I am new to Android programming and have only a little experience in generating interfaces from XML. In programming C# and XML for a previous job, I would have to pull the data directly from an embedded XML file and use that to create the Button or TextBox myself. Do I need to do similar in this case or is there a way to automatically load it?
I have looked this up for a while and most answers I found on this site and other places are from months ago or longer. Those answers tend to range from IMPOSSIBLE to do it yourself. I'm hoping maybe in the past few months there might have been a change to the system I have yet to find.
You are probably looking for a ViewStub.
A ViewStub is an invisible, zero-sized View that can be used to lazily
inflate layout resources at runtime. When a ViewStub is made visible,
or when inflate() is invoked, the layout resource is inflated. The
ViewStub then replaces itself in its parent with the inflated View or
Views. [...]
You can use this like a normal view in your layout and use findViewById() to reference it in code. After that use ViewStub.setLayoutResource() to set layout that you want to show and call ViewStub.inflate() to show it. This way you can write a normal XML
layout file for every (sub-)page you need.
Also see this article.
Edit: Or probably not, I have to mention that the stub gets removed from the view hierachy after inflating. So, depends on your actual use case if this is helpful.