My first question was to click through layout. I solved it out.
Now my question is how to set button's position at desired location?
My application's minimum api level is 8 (I can't set getX() or getLeft())
Test XML code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" >
<Button android:id="#+id/buttonx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="X" />
</LinearLayout>
Acitivty code:
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class Test extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.test);
Button xclose = (Button) findViewById(R.id.buttonx);
xclose.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
finish();
}
});
}
}
any way to change button's position dynamically or programatically?
If you need to align the views in Linear Layout Please read about gravity and layout_gravity properties.
You have another layout like Relative layout. It will give you more properties for view alignment.ex:layout_alignLeft,layout_alignParentLeft etc...
Study about it and use it however you want....Thanks...
You can always use NineOldAndroids by Jake Wharton to use setX() and setY() (and many other properties).
This library ports back the Honeycomb-Animation Framework to api level 1!
If that doesn't work, you could create your own ViewGroup and measure/layout the children yourself. More information here.
EDIT: Also, View.getLeft()/getTop()/... is available since api level 1. See here
Hope this helps!
You can use padding or margin in code for example
xclose.setPadding(left, top, right, bottom);
At the time of onclick u try this
I don't know where do you want to locate your button, but you should look into FrameLayout (which will let you put the button anywhere in your layout).
Using Android, you usually have three layout options as detailed in the Layouts | Android Developers notes. The Linear Layout gives you the option to declare elements and chain them either horizontally or vertically. The Relative Layout, which is what I believe you need, allows you to freely define the position of an element relative to another element, and the Web View is usually used to show web related content.
As I said, I believe the Relative Layout is what you are looking for. Have a look at this example which neatly outlines how to use the different alignment options to place elements. You will not there are two major categories. The first lets you align your element with a parent element which is handy if you want to move elements left, right, top, bottom, or centre. The second lets you define the alignment in regard to elements on the same level by specifying that your element be, for example, android:layout_toLeftOf or android:layout_below. You can combine all of these to get the desired result.
I am well aware that there are many options to achieve the result but I found this to be quite simple and usually sufficient to achieve visually attractive layouts.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/blur2"
android:orientation="horizontal"
tools:context=".MainActivity" >
<Button android:id="#+id/buttonx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="X" />
</RelativeLayout>
Make sure it's relative, not Linearlayout, because on relative it would allow you to move buttons easily.
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 am using a ViewFlipper to display all the measurements the app has made (1 measurement = 1 page element). The problem is, the performance of initializing/reloading of the content of the ViewFlipper gets very bad if there are more then 50 elements. i.e., the app gets unresponsive for about 15 seconds after it has launched. I did some logging and found out, that more than 70% of the loading time is spent on View.inflate(ctx, R.layout.view_measurement, null);
From my understanding, inflate(...) does parse the layout xml file to a View so it can be used in Java. Since the layout xml file is everytime the same, it looks to me like there is the same heavy job being done for each element over and over again. I tried many things to change this and let this happen only one time, unfortunately without success. I also tried to use and tags in the xml also but always got errors.
I know that there are better ways rather than the ViewFlipper to do this job, but as I am in a hurry everything else works fine, I would like to keep this and find a fast solution.
MainActivity.java
...
ViewFlipper viewFlipper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewFlipper = (ViewFlipper)super.findViewById(R.id.measurementsViewFlipper);
int measurementsAmount = 100; //example
for(i=0; i<measurementsAmount; i++){
View measurementView = View.inflate(ctx, R.layout.view_measurement, null);
... fill the view ...
viewFlipper.add(measurementView);
}
...
}
view_measurement.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
...
</LinearLayout>
</RelativeLayout>
The only way to reduce the xml inflation time is to reduce the number of views used in the xml layout. For example, just by looking at he layout you posted, you could(and should) remove the root RelativeLayout if it's just wrapping the LinearLayout. Also, using ConstraintLayout might allow you further remove ViewGroups and reduce the nesting level and the view count.
But this will still not be ok because the real problem is you are inflating a lot of views upfront. In your example if the page layout contains just 5 views you'll create 500 views in total(100 x 5). That's a lot and this is why you need to have a view recycle mechanism so you don't need to create all views upfront, just a few for the current pages.
If you want ViewFlipper's behavior, the Android SDK has a component called AdapterViewFlipper which you should use instead. It just needs an additional adapter class, to which you'll pass the measurement data and in which you'll inflate the measurement layout.
I'm trying to create a pretty simple custom view. However, I need to duplicate this view in my layout a few hundred times which makes the initial drawing very slow (a few seconds). I'm not sure what the best way to approach this is, but I read that having extraneous layouts can slow down the drawing significantly.
When I first designed the custom view, had it extend a LinearLayout and then inflated my view's xml into it. But actually, I feel like the LinearLayout is a waste. Is there a way to cut it out?
Alternatively, is there a more efficient way to create the same view many times?
EDIT
To be clear, the custom views are generated at runtime and the exact number is determined then. Also, these views are embedded in a more complicated layout
Below is my Java class:
public class MyView extends LinearLayout {
public TOCNumBox(Context context) {
super(context);
inflate(context, R.layout.myview, this);
}
}
And here's the XML:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="234">
</TextView>
Are all 100 views being shown at the same time? If not, such as if they are in a scrollable listview, try using a recyclerview to improve performance. Alternatively, you could put all 100 TextViews in a single layout if they do need to be shown at the same time.
I make an timetable application for android and I'm using ViewPagerIndicator as fragment. But now I've a problem, I want to get the TabPageIndicator to the center. Like this:
And I would to like to set the individual tab width and height. And set that tab to a drawable that support selected/pressed states.
I've not found it yet to solve these problems. I've try something with onPageSelected and ContextThemeWrapper but that doesn't work. (Maybe I'm not using it correctly).
Is this all possible to make or should I look to something else than ViewPagerIndicator? (An other option without ViewPagerIndicator is also welcome).
The app on the image is Untis Mobile and can be found on the PlayStore.
I've already ask the creators how they do it but they said the app isn't open source. (But I have found in the source that they do it with TwoDScrollView, but I'm not sure)
Edit:
The styling is fixed with vpiTabPageIndicatorStyle. (With help of XDA Developers!)
When I add 20 items it stays on the middle but only from item 4 to item 17, item 1, 2, 3, 18, 19, 20 are not in the middle. See:
Can I add a 3 empty items (or empty space) to ensure that the first and last items are in the middle? Something like this (from the Untis Mobile app):
(I've already tried android:paddingLeft in vpiTabPageIndicatorStyle but that doesn't work)
I know that viewPager.setCurrentItem(total/2) will set the TabPageIndicator in the middle but then it stays on the middle and I'm not able to select a other day (I call it in onPageScrolled). So I want as you scroll the selected one needs to be in the middle. Is this possible?
The widget you are looking for is similar to the android horizontal wheel. There is an implementation at android-spinnerwheel which can be what you need.
Then you don't need an viewpagerindicator. Use a horizontal scroll view as Amulya Khare suggested in your activity and replace fragments when scrolling occurs.
Your activity layout could be like :
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SomeWheelView
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
<SomeStaticIndicatorView
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
<FrameLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</LinearLayout>
Set a listener to wheelview and when change occurs you can put your fragments in framelayout in your activity.
Use it like this :
TabPagerIndicator tbi;
ViewPager pager;
in onCreate() do like this
tbi=(TabPagerIndicator)findViewById(R.id.something);
tbi.setViewPager(pager);
I hope this will work out for you. :D
I have an android project that has several small views which I need to instantiate at runtime. I haven't been able to figure out a way to store all of these related views in a single xml file and I now there are going to be many of these xml files. I was just wondering if there is any way to have them all in a single file, but not belonging to some parent ViewGroup.
The layout folder in android kinda sucks since there's no way to make subfolders, everything is just piled into the same place, ugh.
I hope someone can tell me of a better way of organizing these things.
If I understand you correctly you want several views meged onto one screen or merged into one xml file. You can include other xml's into one.
The articles showed you how to use the tag in XML layouts,
to reuse and share your layout code. This article explains the tag and how it complements the tag.
http://developer.android.com/resources/articles/layout-tricks-merge.html
Also, this video might help (about 19 minutes in). Shows you how to extract a current layout and be able to include it in others.
a couple things:
Yes, the layout folder is a pain. I use strict naming conventions to make it bearable, and in eclipse use the shortcut ctrl + shift + r to quickly find the layout I am looking for. Try naming your layouts after your activity: activity1_menu_overlay and activity1_main. With the above shortcut, just type out Activity1 and it will only show you the relevant layouts.
And if that doesn't work, you can try wrapping all your views in LinearLayouts and using view.setVisibility(View.Gone); or view.setVisibility(View.Visible); to show/hide the appropriate views.
Here is an example of that second one, because it's tough to explain.
one XML file:
<LinearLayout>
<LinearLayout ... android:visibility="visible">
<copy/paste of view 1>
</Linearlayout>
<Linearlayout ... android:visibility="gone">
<copy/paste of view 2>
</Linearlayout>
<Linearlayout ... android:visibility="gone">
<copy/paste of view 3>
</Linearlayout>
<Linearlayout ... android:visibility="gone">
<copy/paste of view etc.>
</Linearlayout>
</Linearlayout>
keep in mind this approach will require you to define a reference to each "child" LinearLayout view in your activity, so you can call setVisiblity appropriately.
This approach works well for animations, and I would only use it for 2 or 3 possible views in one xml file.