I have implemented a custom keyboard, that is drawn in an ImageView. Now I want to make it floating, it should be placeable anywhere.
The position, width and height is set in the following way:
private void setKeyboardDimensionAndPosition(int widthPI, int heightPI, int xDP, int yDP) {
WindowManager.LayoutParams windowParams = getWindow().getWindow().getAttributes();
windowParams.x = (int) (xDP * GUIManager.getDensity());
windowParams.y = (int) (yDP * GUIManager.getDensity());
windowParams.width = widthPI;
windowParams.height = heightPI;
(new Handler(Looper.getMainLooper())).post(() -> {
getWindow().getWindow().setAttributes(windowParams);
});
}
But the keyboard is always sticked to the text box - it is always below it! It would even be fine when the text box is covered by the keyboard, it should be totally free!
Related
I am noob in android. My problem about useable height of 18:9 devices.
When I try to get useable screen in these aspect-ratio my application is woking fine all android devices but when ı compile in Samsung Galaxy s8 it is not working.
I am trying to get useable screen of devices.
I have already tried method which in these links
https://stackoverflow.com/questions/43628047/how-to-support-189-aspect-ratio-in-android-apps
https://android-developers.googleblog.com/2017/03/update-your-app-to-take-advantage-of.html
And I use dynamically
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
width = metrics.widthPixels;
height = metrics.heightPixels ;
And I tried
private int getSoftButtonsBarHeight() {
// getRealMetrics is only available with API 17 and +
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight)
return realHeight - usableHeight;
else
return 0;
}
return 0;
}
And when I try to set params MATCH_PARENT height it is working good. But I need to find useable height pixel to desing my other views proportionally .
Actually these code DisplayMetrics metrics = this.getResources().getDisplayMetrics();
height = metrics.heightPixels ; working in my Activity but when I try to use it in another window which I extend from FramaLayout and add to activity it is not working.
Here is my code block
public class StudentLoginActivity extends Activity { ...
FrameLayout.LayoutParams containerParams = new ScrollView.LayoutParams(width, height-sb);
container = new FrameLayout(this);
container.setLayoutParams(containerParams);
container.setBackgroundColor(Color.rgb(248,248,248));
loginStudentView = new StudentLoginView(this);
container.addView(loginStudentView); ...
}
public class StudentLoginView extends FrameLayout { ...
FrameLayout.LayoutParams cp = new FrameLayout.LayoutParams(width, height);
setLayoutParams(cp); ...
}
But this problem related with android navigationBar height because when I show navigation bar there is no problem but if I hide navigationBar it is not resize application still working that there is a navigation bar on screen (but I hide the navigationBar).
My problem is very similar this link
android Navigation Bar hiding and persantage of usable screen overlap
You can get the useable height (even on Galaxy S8 with or without shown NavBar) with the decorview:
//Get the correct screen size even if the device has a hideable navigation bar (e.g. the Samsung Galaxy S8)
View decorView = getWindow().getDecorView(); //if you use this in a fragment, use getActivity before getWindow()
Rect r = new Rect();
decorView.getWindowVisibleDisplayFrame(r);
int screenHeight = r.bottom; // =2220 on S8 with hidden NavBar and =2076 with enabled NavBar
int screenWidth = r.right; // =1080 on S8
If you have a view that is set to match the parent width and height (the whole screen), you can attach a listener to that view and then get its width and height.
View myView = findViewById(R.id.my_view);
myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight,
int oldBottom) {
// its possible that the layout is not complete in which case
// we will get all zero values for the positions, so ignore the event
if (left == 0 && top == 0 && right == 0 && bottom == 0) {
return;
}
// Do what you need to do with the height/width since they are now set
}
});
This answer was taken from here.
I am writing an application in which I want to make one activity small when it goes to the background and resize it when it is clicked.
Basically I want a floating window like Skype video call floating window.
I have tried to add an child activity for the main activity but I cannot afford to create another activity again, so my idea is to make this current activity small when go to background and resize it when it is clicked.
To make is small I do this
//Get the window
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,WindowManager.LayoutParams.FLAG_DIM_BEHIND);
// Params for the window.
// You can easily set the alpha and the dim behind the window from here
WindowManager.LayoutParams params = window.getAttributes();
params.alpha = 1.0f; // lower than one makes it more transparent
params.dimAmount = 0f; // set it higher if you want to dim behind the window
window.setAttributes(params);
// Gets the display size so that you can set the window to a percent of that
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
// You could also easily used an integer value from the shared preferences to set the percent
if (height > width) {
window.setLayout((int) (width * .35), (int) (height * .30));
} else {
window.setLayout((int) (width * .20), (int) (height * .35));
}
Now I want to set the onclicklistener on the window to make is bigger when clicked.
Thanks for your help in advance.
I have a Sudoku grid image loaded into my app, but I'm having a lot of trouble getting EditTexts to appear in each square. When I run the app, the numbers in the EditTexts are hardly visible. I've tried changing the background color and text color and nothing has changed.
/* PROGRAMATICALLY ADD EDITVIEWS via waiting for draw */
layout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener()
{
public void onGlobalLayout()
{
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
/* not used yet
int height = grid.getMeasuredHeight();
int width = grid.getMeasuredWidth();
int top = grid.getTop();
//int bottom = grid.getBottom();
int left = grid.getLeft();
int square_height = height/9;
int square_width = width/9;*/
for ( int r = 0; r < 9; r++ )
{
for ( int c = 0; c < 9; c++ )
{
text_boxes[r][c] = new EditText(getApplicationContext());
text_boxes[r][c].setId(r+c);
text_boxes[r][c].setText("1");
text_boxes[r][c].setInputType(InputType.TYPE_CLASS_NUMBER);
text_boxes[r][c].setFilters(new InputFilter[] {new InputFilter.LengthFilter(1)});
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(c*10, r*50, 0, 0);
layout.addView(text_boxes[r][c], params);
text_boxes[r][c].setBackgroundColor(0x0FF00);
}
}
}
});
you didn't remove the listener when you are finished using it, so it can keep being called.
also, about the color of the EditText, you can change it to whatever you wish , by just changing the background of the EditTexts, or use a global style that sets a default background for EditTexts. you can even use this tool
I'm wondering what would be the best solution to get to the result shown below.
Here is what i've found so far:
an ImageView for the forest and a transparent surfaceView (to handle touch) on which I would draw the rectangles?
Or...
Just One SurfaceView with the image set as background and rectangles directly drawn on...?
For those 2 I've already chosen a RelativeLayout.
Which of those 2 would be the most efficient and easiest to do?
Or maybe there is another way which I haven't think about.
In any case thanks for your advice, here is what I tend to...
I've implemented this by placing the image in a RelativeLayout (FrameLayout would work too), and then adding each outlined view programatically. If you know the x and y origin (perhaps as a ratio to the image) and the size for each area, you can easily inflate each view/area (with a black border, transparent center), make it clickable and set a listener, and then set it's origin by adjusting it's margins. You may want to perform all of this after the image has finished laying out:
I put this in onActivityCreated of my Fragment, but other lifecycle methods would work too...
ViewTreeObserver vto = image.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (image.getMeasuredHeight() > 0) {
addHotSpots();
ViewTreeObserver obs = image.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
}
}
});
And this is how I actually place all the hotspots/areas:
protected void addHotSpots() {
HotSpot[] hotSpots = res.hotspots;
for (HotSpot hs : hotSpots) {
addHotSpotToImage(hs);
}
private void addHotSpotToImage(HotSpot hs) {
int height = image.getMeasuredHeight();
int width = image.getMeasuredWidth();
//this piece will probably be different for you
//depending on what you know about the area's intended size/position
double hsHeightRatio = hs.lr.y - hs.ul.y;
double hsWidthRatio = hs.lr.x - hs.ul.x;
double leftMargin = hs.ul.x * width;
double topMargin = hs.ul.y * height;
double hsHeight = height * hsHeightRatio;
double hsWidth = width * hsWidthRatio;
LayoutInflater vi = (LayoutInflater) image.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View newSpot = vi.inflate(R.layout.question_hotspot, null);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) hsWidth, (int) hsHeight);
newSpot.setTag(hs.key);
newSpot.setFocusable(true);
newSpot.setClickable(true);
newSpot.setFocusableInTouchMode(true);
newSpot.setOnTouchListener(this);
params.topMargin = (int) topMargin;
params.leftMargin = (int) leftMargin;
image.addView(newSpot, params);
}
I'm trying to make a dynamic grid layout, it being API 10+ is the part that's been making it slow going. I tried to make it wrap automatically.. but in the end found it easier just to try to force it into a grid pattern using coordinates. This script was working by itself when I did the positioning at time of creation, but now I am trying to loop through each item as a sort. So if one item is deleted, they all float back into a grid without a hole in the middle.
Problem is, it seems the layout parameters are only applying to the last object.
Here's some base variables and onCreate setup:
int screenWidth;
int screenHeight;
int distStep = 130;
int leftPad = 20;
int numCols;
int baseID = 0;
android.util.DisplayMetrics metrics = this.getResources().getDisplayMetrics();
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
numCols = (int) (screenWidth - leftPad) / distStep;
int scrRemain = screenWidth - ((numCols * distStep) + leftPad);
distStep += (int) scrRemain / numCols;
Then on to the main function for adding:
public void addObjToLayout() {
RelativeLayout relLay = (RelativeLayout) this.findViewById(R.id.mainWindow);
for(int i = 1; i <= currQuantity; i++){
TextView tv=new TextView(this);
tv.setTextSize(40);
tv.setId(baseID + i);
tv.setPadding(24, 4, 24, 4);
tv.setBackgroundColor(0x110000FF);
tv.setText(String.valueOf(baseID + i)); //Val for debugging
tv.setTextColor(0xFFFFFFFF);
relLay.addView(tv);
}
baseID += currQuantity;
sortLayout();
}
Then the sorting:
public void sortLayout() {
int leftNum = 20;
int topNum = 0;
for(int i = 1; i <= baseID; i++){
TextView tv= (TextView) this.findViewById(baseID);
MarginLayoutParams mp = new MarginLayoutParams(tv.getLayoutParams());
mp.setMargins(leftNum, topNum, 0, 0);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mp);
tv.setLayoutParams(lp);
leftNum += distStep;
if(leftNum >= distStep * numCols){
leftNum = leftPad;
topNum += distStep;
}
}
}
What I am getting is all the textViews pile up in the top left corner, except the last one which is positioned exactly where it should be. So it seems in my head, the params object isn't applying until the loop ends or something.. but logically I don't see why.
As I said, this worked when I set the params at the get go, problem is mass updating them all at once. I am pretty new to android, so I hope I'm not just doing something stupid.
Thanks for your time
Margin means it will set a gap between the previous view and current view.
When you add view1, view2 and view3 to grid layout and if you remove view2 at some point of time, then the margin for view3 is set according to view1. So, it won't leave empty space in place of view2. Instead of removing view2 at run time, set the background for view2 as null and set the text as empty as below.
textView.setBackground(null);
textView.setText("");
So that the view is still available but looks as deleted.
Started looking into GridView using an extended baseAdapter. Looks promising:
For more (see #2):
http://www.mkyong.com/android/android-gridview-example/