I am a newbie, so, any help is appreciated. I read a lot of posts here at StackOverflow and also I searched for my doubt in Google, but it's hard to find a good answer.
Here is what I am trying to do:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<ImageButton
android:background="#layout/roundcorners"
android:id="#+id/hug"
android:scaleType="centerInside"
android:cropToPadding="false"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingBottom="10dip"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:src="#drawable/hug">
</ImageButton>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:textColor="#000000"
android:textSize="15dip"
android:textStyle="bold"
android:paddingBottom="5dip"
android:clickable="true"
android:text="Hug">
</TextView>
</FrameLayout>
Above you guys can see the XML version of what I need.
The point is... I will have many of these FrameLayouts at run time. Every information to fill out the buttons will come from a database.
So, I need to create a Java Class where I can use a loop through all the registers from my database and instantiate a new FrameLayout Class (this class must have an ImageButton and a TextView as you can see from above XML) and just pass parameters, like this:
for (int i = 0; i < mArray.length; i++) {
button = new MyNewImageButton(name, src, text);
}
The above is just to simplify. What I mean is that I will pass parameters from my database when creating an Instance of this class that I am planning to create. Of course, every single button created will be added to the layout.
So... my question is: I know how to do this using XML, but I am REALLY having a hard time to create a class to do this.
Any thoughts? Any help is appreciated.
P.S.: Sorry if I made any mistake in my English, ok? I am a Brazilian. Someday my English will be flawless! Sorry if this question was already answered.
sorry to answer my own question to make another question. I tried to use the comments but there's a limitation in the number of characters, so, I am really sorry.
Hey guys and #blessenm. Well... I tried to use inflater and I came up with the following code:
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// *******************************************
setContentView(R.layout.main);
//this is my main screen
//it's a linearlayout vertical orientation
ViewGroup parent = (ViewGroup) findViewById(R.id.tela_principal);
//these two new LinearLayouts will be one above the other,
//just like two lines
LinearLayout l1 = new LinearLayout(this);
LinearLayout l2 = new LinearLayout(this);
//inside of each linearlayout I set the orientation to horizontal
//so, everytime a picture is inflated from xml, it will fill in one
//linearlayout
l1.setOrientation(LinearLayout.HORIZONTAL);
l2.setOrientation(LinearLayout.HORIZONTAL);
//setting linearlayout parameters, so they fill the whole screen
l1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
l2.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
//the first two inflated xml imagebuttons I add to LinearView1
view = LayoutInflater.from(getBaseContext()).inflate(R.layout.figurabotao,
l1, true);
view = LayoutInflater.from(getBaseContext()).inflate(R.layout.figurabotao,
l1, true);
//the next two inflated xml imagebuttons I add to LinearView2
view = LayoutInflater.from(getBaseContext()).inflate(R.layout.figurabotao,
l2, true);
view = LayoutInflater.from(getBaseContext()).inflate(R.layout.figurabotao,
l2, true);
//after the above, we should have a grid 2X2
//after linearlayouts are filled, I add them to the main screen
parent.addView(l1, new LinearLayout.LayoutParams(0, 0, 1));
parent.addView(l2, new LinearLayout.LayoutParams(0, 0, 1));
However this is not working. In the errorlog I get the following message:
"Unhandled event loop exception".
Any ideas about what I am doing wrong?
Thanks!
If you are just trying to create a view from the xml and add it to the layout. Just use the LayoutInflater.
Inside the activity use something like
FrameLayout frame = (FrameLayout)getLayoutInfalter.inflate(
R.id.YOUR_VIEW_XML,null);
layout.addView(frame);
If you are trying to create a class extend the frame layout or the the view. Create a constructor which takes your parameters and assign's the required values.
EDIT:
To Acess Elements Inside
If you have set id's to those element, you can access them by
TextView text = (TextView)frame.findViewById(R.id.yourtextview);
Or you can use the child index like
TextView text = (TextView)frame.getChildAt(0);
It sounds like you are looking for a way to create a view class that will be an ImageButton and a TextView wrapped with a FrameLayout.
In this case, you could look into creating your own View class. Probably a View class that extends FrameLayout. See this dev article for more information about how to create a custom view. http://developer.android.com/guide/topics/ui/custom-components.html
Specifically the "Compound Controls" section: http://developer.android.com/guide/topics/ui/custom-components.html#compound
Related
I have a vertical LinearLayout in my app where every row should get a more complex sub-view consisting of an image and two lines of text. Now I want to make the complete row clickable in order to start an other action. This means the whole thing should react on a click: the base view which holds the other elements, the image and even the two lines of text.
My question: what is the best approach for this? I can't use a simple button for the complete row and as far as I know I can't set an onClick-Handler for view/image/labels?
Any idea how this could be done?
Thanks!
The easiest option would be to put android:descendantFocusability="blocksDescendants" on your parent view, this will block any child view from taking clicks from the parent, then put a click listener on the parent only.
This is assuming you don't care on which child view exactly the user clicked within the parent.
<LinearLayout
android:id="#+id/parent"
...
android:clickable="true"
android:descendantFocusability="blocksDescendants" >
<TextView
... />
<ImageButton
... />
</LinearLayout>
and in code:
LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
parent.setOnClickListener(...);
You just need to add clickable tag true in xml to your main view eg relativelayout or linearlayout.
That will work
This is how I did it. Just loop over the childen and make then non clickable. This works even if you are using clickable items inside root view.
rootView.apply {
descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
isClickable = true
setOnClickListener {
Snackbar.make(it, "$data", Snackbar.LENGTH_LONG).show()
}
children.forEach {
it.isClickable = false
}
}
I am trying to set a custom view in an ActionBar. I am using the support.v7 ActionBar - min API is 9. For some odd reason, I cannot get the custom view to appear in the ActionBar. Am I missing something painfully obvious? Any help appreciated.
Here is the layout I am inflating:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="flsfjkelsjek"
android:background="#color/black"
android:textColor="#color/white"
/>
...Very simple, just a TextView for testing.
Here is the code to set this view as my custom ActionBar view:
TextView customView = (TextView) myInflater.inflate(R.layout.my_test_textview, null);
myActionBar.setDisplayShowTitleEnabled(false);
myActionBar.setDisplayHomeAsUpEnabled(true);
myActionBar.setDisplayShowCustomEnabled(true);
myActionBar.setCustomView(customView, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
Again, very simple and straightforward. I have tried many different varations on this, such as:
mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_SHOW_TITLE);
and have even tried that line along with all of the above. I've also tried with a TextView just created on the fly, rather than inflating one.
The custom view simply doesn't appear. When I check the value of
myActionBar.getCustomView()
it returns my TextView. However, the width of that TextView is 0. Does anyone have any idea why the CustomView is not showing up?
I'm a relative beginner with Java and I'm still struggling somewhat with views. I've not had much success with searching through other posts or on-line tutorials. I won't post any code for this because I suspect many of you will know what's going on.
I have a canvas that allows me to draw lines on the screen with my finger, etc. I've got it working fine. My next task is to use a command button to save it as an image. The canvas covers the whole screen so the button I inserted on to the layout (in activity_main.xml) can't be seen.
My specific question is do I deal with the size of the canvas and access to the command button through a method(s) in the DrawView.java class or in the XML file in layout? Links to any good tutorials would be great. Thanks.
Use FrameLayout to show it overlappingly
In the XML the button would come below your View whose Canvas you are drawing on.
Frame Layout Example
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#D6FFD6"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:src="#drawable/android"
android:scaleType="fitCenter"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
<TextView
android:text="learnandroideasily.blogspot.com"
android:textSize="30sp"
android:textStyle="bold"
android:textColor="#003399"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="center"/>
</FrameLayout>
Update based on your comments
This does the entire layout dynamically, no button in the XML needed. Replace TextView or ImageView with your button. Change parameters accordingly.
public class BlahActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout rl = new FrameLayout(this);
rl.addView(cv, GlobalVars.screenWidth, GlobalVars.screenHeight);
setContentView(rl);
ImageView fs = new ImageView(this);
fs.setImageResource(R.drawable.icon);
rl.addView(fs);
TextView fs = new TextView(this);
fs.setText("Bar seco");
fs.setTextColor(android.R.color.white);
fs.setTextSize(1,14);
fs.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
rl.addView(fs);
}
}
I made a list view by the android.com's tutorial, and its in a tab widget, but the problem is that its spreading all over the tab's area and I want to create 2 lists in one tab, one beside the other... how can I do that?
here is a link to the tutorial:
http://developer.android.com/resources/tutorials/views/hello-listview.html
EDIT: ok that what I have in the onCreate method, there are 2 static final String arrays in this class called CONTACTS and FAVORITES, I copied MH's layout to an xml file called list_who and changed the IDs to lv_cons and lv_vav, and another layout called tv (TextView) that only have a text view because that what the adapter requires
super.onCreate(savedInstanceState);
ListView lv_cons = (ListView) findViewById(R.id.lv_cons);
ListView lv_fav = (ListView) findViewById(R.id.lv_fav);
lv_cons.setAdapter(new ArrayAdapter<String>(this, R.layout.tv, CONTACTS));
lv_fav.setAdapter(new ArrayAdapter<String>(this, R.layout.tv, FAVORITES));
setContentView(findViewById(R.layout.list_who));
If you want two display two lists side-by-side, there are a few things you'll need to change.
First the (minimal) layout for the tab's content:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/left_listview"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1" />
<ListView
android:id="#+id/right_listview"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
If you followed the Hello ListView sample code you linked, you'll have to change your ListActivity back to Activity. The former basically offers a number of convenience methods for working with a single list, but you can do exactly the same with a regular activity, which you'll need to work with multiple lists.
You can inflate your ListViews like any other view by using their ids (there is no more getListView() convenience method, since we're not extending ListActivity anymore)`:
ListView leftList = (ListView) findViewById(R.id.left_listview);
ListView rightList = (ListView) findViewById(R.id.right_listview);
From that point on you can add all stuff to populate/manipulate the lists' contents.
//Edit: If you insist on creating the layout programmatically, simple convert above xml code to it's Java equivalent:
// Create ViewGroup as container for both lists
LayoutParams rootParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
LinearLayout root = new LinearLayout(this);
root.setLayoutParams(rootParams);
// Create LayoutParams for the lists - both identical in this example
LinearLayout.LayoutParams listParams = new LinearLayout.LayoutParams(0, LayoutParams.FILL_PARENT);
listParams.weight = 1;
ListView leftList = new ListView(this);
ListView rightList = new ListView(this);
leftList.setLayoutParams(listParams);
rightList.setLayoutParams(listParams);
// Add lists to container
root.addView(leftList);
root.addView(rightList);
// Set container as content view
setContentView(contentView);
If you're looking to handle two separate ListViews in separate tabs (i.e. a ListView in each tab), then follow this tutorial: Android TabActivity with two list views.
You simply need to make one composite layout and extract your tabHost from the xml programmatically and then inflate the tabs on the fly. I further suggest using this method if you want two lists to communicate with each other via an Intent. Both tabs would be hosted in one activity. If I misunderstood your question and you want to display two separate, adjacent lists within one activity..then disregard my answer.
I think this is what you're looking for. Good luck.
Can you overlay a view on top of everything in android?
In iPhone I would get the new view set its frame.origin to (0,0) and its width and height to the width and height of self.view. Adding it to self.view would then cause it to act as an overlay, covering the content behind (or if it had a transparent background then showing the view behind).
Is there a similar technique in android? I realise that the views are slightly different (there are three types (or more...) relativelayout, linearlayout and framelayout) but is there any way to just overlay a view on top of everything indiscriminately?
Simply use RelativeLayout or FrameLayout. The last child view will overlay everything else.
Android supports a pattern which Cocoa Touch SDK doesn't: Layout management.
Layout for iPhone means to position everything absolute (besides some strech factors). Layout in android means that children will be placed in relation to eachother.
Example (second EditText will completely cover the first one):
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/root_view">
<EditText
android:layout_width="fill_parent"
android:id="#+id/editText1"
android:layout_height="fill_parent">
</EditText>
<EditText
android:layout_width="fill_parent"
android:id="#+id/editText2"
android:layout_height="fill_parent">
<requestFocus></requestFocus>
</EditText>
</FrameLayout>
FrameLayout is some kind of view stack. Made for special cases.
RelativeLayout is pretty powerful. You can define rules like View A has to align parent layout bottom, View B has to align A bottom to top, etc
Update based on comment
Usually you set the content with setContentView(R.layout.your_layout) in onCreate (it will inflate the layout for you). You can do that manually and call setContentView(inflatedView), there's no difference.
The view itself might be a single view (like TextView) or a complex layout hierarchy (nested layouts, since all layouts are views themselves).
After calling setContentView your activity knows what its content looks like and you can use (FrameLayout) findViewById(R.id.root_view) to retrieve any view int this hierarchy (General pattern (ClassOfTheViewWithThisId) findViewById(R.id.declared_id_of_view)).
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id = "#+id/Everything"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- other actual layout stuff here EVERYTHING HERE -->
</LinearLayout>
<LinearLayout
android:id="#+id/overlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right" >
</LinearLayout>
Now any view you add under LinearLayout with android:id = "#+id/overlay" will appear as overlay with gravity = right on Linear Layout with android:id="#+id/Everything"
You can use bringToFront:
View view=findViewById(R.id.btnStartGame);
view.bringToFront();
The best way is ViewOverlay , You can add any drawable as overlay to any view as its overlay since Android JellyBeanMR2(Api 18).
Add mMyDrawable to mMyView as its overlay:
mMyDrawable.setBounds(0, 0, mMyView.getMeasuredWidth(), mMyView.getMeasuredHeight())
mMyView.getOverlay().add(mMyDrawable)
I have just made a solution for it. I made a library for this to do that in a reusable way that's why you don't need to recode in your XML. Here is documentation on how to use it in Java and Kotlin. First, initialize it from an activity from where you want to show the overlay-
AppWaterMarkBuilder.doConfigure()
.setAppCompatActivity(MainActivity.this)
.setWatermarkProperty(R.layout.layout_water_mark)
.showWatermarkAfterConfig();
Then you can hide and show it from anywhere in your app -
/* For hiding the watermark*/
AppWaterMarkBuilder.hideWatermark()
/* For showing the watermark*/
AppWaterMarkBuilder.showWatermark()
Gif preview -
I have tried the awnsers before but this did not work.
Now I jsut used a LinearLayout instead of a TextureView, now it is working without any problem. Hope it helps some others who have the same problem. :)
view = (LinearLayout) findViewById(R.id.view); //this is initialized in the constructor
openWindowOnButtonClick();
public void openWindowOnButtonClick()
{
view.setAlpha((float)0.5);
FloatingActionButton fb = (FloatingActionButton) findViewById(R.id.floatingActionButton);
final InputMethodManager keyboard = (InputMethodManager) getSystemService(getBaseContext().INPUT_METHOD_SERVICE);
fb.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// check if the Overlay should be visible. If this value is false, it is not shown -> show it.
if(view.getVisibility() == View.INVISIBLE)
{
view.setVisibility(View.VISIBLE);
keyboard.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
Log.d("Overlay", "Klick");
}
else if(view.getVisibility() == View.VISIBLE)
{
view.setVisibility(View.INVISIBLE);
keyboard.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
bringToFront() is super easy for programmatic adjustments, as stated above. I had some trouble getting that to work with button z order because of stateListAnimator. If you end up needing to programmatically adjust view overlays, and those views happen to be buttons, make sure to set stateListAnimator to null in your xml layout file. stateListAnimator is android's under-the-hood process to adjust translationZ of buttons when they are clicked, so the button that is clicked ends up visible on top. This is not always what you want... for full Z order control, do this: