In my XML layout I have some TextView with ids like slot0, slot1...slot15.
Is there any way to generate the corresponding Id dynamically in java like the following?
findViewById(R.id.*customStringForId*)
then access each of TextView using a for loop?
I am currently unable to use findViewById(R.id.*customStringForId*) because I can't find it in the XML.
Thats a bad practice for access component from your xml
You need set manual for id with findViewById for tell java class if in your xml there existing textview with id which already you set and give you access for do whatever like implement onclick event, settext, etc.
If you cant find your id, you need check if setContentView in your java point to your xml.
there are some ways to solve your problem but you should write your layout in the question to let us know how you design the layout.
But for example if you have a list of TextViews inside layout like the following:
<LinearLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/slot0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="example" />
<TextView
android:id="#+id/slot1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="example" />
<TextView
android:id="#+id/slot2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="example" />
</LinearLayout>
you can access the TextView Dynamically via the layout like the following:
public TextView getTextView(int index){
return ((LinearLayout) findViewById(R.id.layout)).getChildAt(index)
}
Related
I'm trying to add a "You are offline" element to the bottom of each layout in my Android app. I would like to define it globally, not to paste the same element to each xml layout file.
I could probably create some ParentActivity and append it programmatically, but is it a good solution?
What is the best way?
Thanks.
Use custom BottomSheetDialog. You do not have to inclue it in layout file. Instead, you will call it programmatically.
BottomMessageDialog:
public class BottomMessageDialog extends BottomSheetDialog {
public BottomMessageDialog(#NonNull Context context) {
super(context);
setContentView(R.layout.dialog_bottom_message);
}
}
dialog_bottom_message.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="You are offline"
android:textSize="18sp"
android:gravity="center"/>
</LinearLayout>
Call it:
BottomMessageDialog bottomMessageDialog = new BottomMessageDialog(MainActivity.this);
bottomMessageDialog.show();
Hope it will help.
best way is creating a custom xml file with any name you want and you can use it any number of times you want without any copy and paste.
step 1: creating custom layout named footer_message .
<TextView
android:layout_width="match_content"
android:layout_height="wrap_content"
android:text="You are Offline"/>
step 2: adding that custom layout in another xml which you want that msg.
<include
android:id="#+id/footer_message"
layout="#layout/footer_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
create an xml file
footer.xml
make your layout in it and write this code in the xml files where you want that footer
<include
android:layout_height="wrap_content"
android:layout_width="fill_parent"
layout="#layout/footer"
android:id="#+id/footer"/>
There is the DismissOverlayView, which you can implement to give the user an alternative way to exit the application on an android watch. This View implements something, that looks like a fullscreen FAB. Now I would like to know, how I could implement the same View with another button icon/color/behaviour. Since you can't change the DismissOverlayView which code looks btw. like this :
<android.support.wearable.view.DismissOverlayView
android:id="#+id/dismiss_overlay"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
I guess you have to implement some custom FAB, but I can't use the FAB in my watch XML either because there is an dependency missing or because it's simply not supported by the watch os. I tried following code for testing :
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_margin="16dp"
android:clickable="true"/>
Edit: For better understanding, I want the button look like this :
Edit: I just found this solution, I was not aware of that one :
https://developer.android.com/training/wearables/ui/confirm.html
But I would still be curious, if you could implement a more customisable version of this buttons.
Okay I found a solution for that problem, actually you can simply create a new layout.xml and overwrite the default code, which is the following one :
<merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/dismiss_overlay_explain"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="32dp"
android:layout_width="wrap_content"
android:padding="12dp"
style="#style/DismissOverlayText"
/>
<android.support.wearable.view.ActionPage
android:id="#+id/dismiss_overlay_button"
android:layout_height="match_parent"
android:background="#color/dismiss_overlay_bg"
android:layout_width="match_parent"
android:src="#drawable/ic_full_cancel"
android:color="#color/dismiss_close"
app:buttonRippleColor="#color/dismiss_close_pressed"
android:text="#string/dismiss_overlay_button_label"
/>
</merge>
Now you can use your newly created xml customise it and use this one instead of the original dimissOverlayView. But you should be careful with doing so, because this is not really intended from the design guidelines to do.
I know that this topic is nothing new, but I really got stuck with this and tried a lot of answers and still I can't make it clear what and where should I write and use.
I have this layout file settings.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
...
<TextView
android:id="#+id/pass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginTop="10dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/pass_del"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="7dp"
android:layout_marginTop="7dp"
android:text="Удалить пароль"
android:textAppearance="?android:attr/textAppearanceMedium" />
...
</LinearLayout>
I have TextView passdel that I want to add programmatically. Its onCreate description is passdel=(TextView) findViewById(R.id.pass_del);
And I have these methods
public void onPasSet() {
pass.setText("Сменить пароль");
((LinearLayout)passdel.getParent()).addView(passdel);
}
public void onPasDel() {
pass.setText("Установить пароль");
((LinearLayout)passdel.getParent()).removeView(passdel);
}
onPasDel is working well.
I guess Java takes current layout. So when I remove View, it's on this layout. And when I try to add this View, Java tries to find this view on current layout, but it's removed, so ..nullpointerexception. How should I write all addView stuff properly? How to point on the needed layout?
Why do you need to remove/add this View? If I understood the goal of this component correctly, the best way will be just to hide/show it:
passdel.setVisibility(View.GONE);
passdel.setVisibility(View.VISIBLE);
Of course, after you've removed passdel from ViewGroup, it has no parents anymore, so you'll get NPE while trying to call onPasSet() after onPasDel()
As you suggested, getParent() won't work intil TextView is not instantiated.
You should get Layout in different way.
You can do it by findViewById(R.id.layout.id).
Example:
In XML:
<LinearLayout
...
android:id="#+id/my_layout">
...
In Activity:
LinearLayout ll = (LinearLayout) findViewById(R.id.my_layout);
ll.addView(myView);
I am a novice learning Android development and the next step I must take is to be capable to understanding threads to be able to implement a game loop.
I have taken knowledge from google and StackOverflow and snippets from examples to come up with a lump of code that seems to not be working:
MainActivity.java
GameSetup.java
GameView.java
activity_main.xml
game_setup.xml
MainActivity.java is a simply title screen with a play button. This seems to work fine and will link to the next activity. However, I am getting a crash whenever I attempt to load up the next activity. My guestimations based on the error lead me to believe that threads have issues with RelativeActivity, but I'm not so sure on what the issue may be exactly, I am rather confused.
Here is the error I am getting thrown, I am having issues trying to decipher the issue with it.
Thanks.
R.id.layout is a RelativeLayout but you are trying to cast it to GameView, that's causing your crash.
Edit:
To add your GameView to the RelativeLayout you can do
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.your.package.GameView
android:id="#+id/my_game_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ship1" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ship1" />
</RelativeLayout>
and retrive it with
GameView myGameView = (GameView) findViewById(R.id.my_game_view);
Hmm, from the code you have written so far, I can explain the reason for the ClassCastException.
You are declaring a RelativeLayout in both XML files.
Both RelativeLayouts use the same android:id "#+id/layout"
In GameView.java you try to find a view by specifying the id
m_game = (GameView) findViewById(R.id.layout);
IMO you are retrieving one of the RelativeLayouts and then try to cast it to a GameView. As this is not possible, Java throws the exception.
I'm trying to program a disc golf scoring app on Eclipse for my android phone. I'd like to set it up for up to 6 players, but mostly 2 people will use it for a game. The data is being stored in a sqlite DB, and I am using a SimpleCursorAdapter to populate the data for holes that have already been scored. here is that code:
private void fillData() {
Cursor notesCursor = mDbHelper.fetchAllNotes();
startManagingCursor(notesCursor);
// Create an array to specify the fields we want to display in the list (only TITLE)
String[] from = new String[]{DiscGolfDbAdapter.KEY_HOLE,
DiscGolfDbAdapter.KEY_PAR,
DiscGolfDbAdapter.KEY_TOM_HOLE,
DiscGolfDbAdapter.KEY_TOM_GAME,
DiscGolfDbAdapter.KEY_CRAIG_HOLE,
DiscGolfDbAdapter.KEY_CRAIG_GAME,
DiscGolfDbAdapter.KEY_TOMS_POSITION,
DiscGolfDbAdapter.KEY_SKIP_PLAYER
};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.schole, R.id.scpar, R.id.scth, R.id.sctg, R.id.scch, R.id.sccg, R.id.sctp,
R.id.skip};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter notes =
new SimpleCursorAdapter(this, R.layout.hole_info, notesCursor, from, to);
setListAdapter(notes);
}
From searching the internet I've found what I think are two posibilities that SHOULD work, but do not.
First I've tried the XML Attribute: android.visibility. It looks like this in the PORTION of the view that I am trying to "test" hide:
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android.visibility="GONE">
<TextView android:id="#+id/scch"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/sccg"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
</LinearLayout>
I have tried it with "GONE", "Gone" and "gone". NONE of them work in the eclipse emulator OR on my actual phone. So, there is no point in trying to parameterize this attribute.
Next I've tried setting the XML attribute for android:layout_height to "0dip". This indeed works in the emulator and on my phone WHEN IT IS HARDCODED.
Then I moved to the next logical step (as I see it), storing a parameter in the DB so that I can "show" or "not show" the item DEPENDING on conditions within the record. So, I've stored a field in the DB with two values "0dip" and "wrap_content". I pass these to the layout as shown in the java above as R.id.skip. I've also added these to the output just to audit that they are really there. Here is that XML:
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="#+id/skip">
<TextView android:id="#+id/scch"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/sccg"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView android:id="#+id/skip"
android:gravity="center"
android:layout_width="315dip"
android:textSize="10sp"
android:layout_height="wrap_content"/>
In the above test, both via the Eclipse emulator and my android phone, the last TextView confirms that the DB contains either "0dip" or "wrap_content", BUT the LinearLayout with:
android:layout_height="#+id/skip">
behaves as if it were "0dip" ALL of the TIME. In other words, I cannot PROGRAMMATICALLY" affect the XML attribute for android:layout_height.
If there is a better/more standard way of accomplishing what I am trying to do, please share - BUT BE CLEAR. I am new, so CODE EXAMPLES wwill work best for me.
May 29th - It seems to me (based on testing) that you cannot alter layout attributes for the layout specified in this code:
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.hole_info,
notesCursor, from, to);
setListAdapter(notes);
Anything I try leads to some error ort another. So, I've seen examples of custom list adapters where these attributes are altered, so I'm trying to convert to a custom list adapter.
Why not do it in code?
LinearLayout ll = (LinearLayout)findViewById(R.id.your_layout_id);
ll.setVisibility(View.GONE);
Your XML layout code
android.visibility="GONE"
should be
android:visibility="GONE"
Change visible of a LinearLayout like Gabriel Neguţ say:
LinearLayout ll =
(LinearLayout)findViewById(R.id.your_layout_id);
ll.setVisibility(View.GONE);
or change height of LinearLayout:
LinearLayout ll = (LinearLayout)findViewById(R.id.your_layout_id);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
lp.height = 0; // or lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
ll.setLayoutParams(lp);
What about this guy's solution http://enjoyandroid.wordpress.com/2012/03/12/customizing-simple-cursor-adapter/
Kind of worked for me.