What is a possible use case for duplicate +id layout-wide? - android

We don't have a compilation problem, we just want to expand our knowledge. Reading through Google Code Documentation, we have read that +id doesn't have to be unique layout-wide.
Below a compiling example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
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"
android:orientation="vertical"
tools:context="com.bq.testviewids.MainActivity">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hola Mundo" />
</LinearLayout>
private void initViews() {
txtText = (TextView) findViewById(R.id.text);
txtText.setId(View.generateViewId());
txtText = (TextView) findViewById(R.id.text);
}
private void changeTextView() {
txtText.setText("");
}
If in initViews() we don't have the last two lines:
txtText.setId(View.generateViewId());
txtText = (TextView) findViewById(R.id.text);
When we do a change to txtText (in changeTextView()), the first TextView gets modified.
If we do have the last two lines the second TextView gets modified.
We didn't know that this was possible, and we thought that if you had two items layout-wide with the same +id, it wouldn't compile. Now, we understand that the identifier doesn't have to be unique in this view's hierarchy, but, we don't understand the usefulness of this behavior.
Does someone know a use case in which a non-unique identifier is useful?
This doubt comes to us when we see in Android for MSM (CAF) in Settings project this code with a duplicate id (#+id/fields):
<LinearLayout android:id="#+id/fields"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/wifi_section"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/wifi_item">
...
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/wifi_item">
...
</LinearLayout>
<LinearLayout android:id="#+id/fields"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/wifi_section" >
...
</LinearLayout>

The use case that comes to mind are the duplicate id's that you would have if you have a layout that is included two or more times in another layout. It would save you the headache of trying to get unique id's in each duplicated layout.
It would also allow you to work within each included layout using the same code without having to track different id's depending upon which sub-layout you are working on.

Related

How to resolve hint character wrapping on autosizing TextView with empty text on android?

I want to use autosizing TextView for dynamic text content.
<?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">
<TextView
android:layout_width="match_parent"
android:layout_height="350dp"
android:autoSizeTextType="uniform"
android:hint="hint"
android:text="some dynamic text" />
</LinearLayout>
This works so far:
But there is an issue if the dynamic text content is empty. The TextView wraps each character of the hint content to a new line:
I expect hint to behave like text. How to resolve this without hacks like setting text content to hint content if the former is empty.
The same event happened to me.
I defined this and it fixed it.
app:autoSizeStepGranularity="1dp"
I'd definitely set the minimum and maximum sizes together.
android:hint="no message"
app:autoSizeMaxTextSize="20sp"
app:autoSizeMinTextSize="1sp"
app:autoSizeStepGranularity="1sp"
app:autoSizeTextType="uniform"
layout.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/show"
android:layout_width="match_parent"
android:layout_height="350dp"
android:hint="no message"
/>
</RelativeLayout>
MainActivity.java
TextView shows = findViewById(R.id.show);
TextViewCompat.setAutoSizeTextTypeWithDefaults(shows,
TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM);
if(message.isEmpty()){
shows.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
}else{
shows.setText(message);
shows.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
}
if you add this code please run the code.

Getting a View with a duplicate id from a layout

I would like to display the following five times
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/title"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/message"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/add"/>
<View
android:layout_width="match_parent"
android:layout_height="#dimen/separator_height"
android:background="#color/separator"/>
Thus I store it in data_item.xml and try calling it via
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:id="#+id/data_one"
android:layout_height="match_parent">
<include layout="#layout/data_item"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:id="#+id/data_two"
android:layout_height="match_parent">
<include layout="#layout/data_item"/>
</LinearLayout>
However if I do that, then all of the items inside data_item.xml layout are going to have duplicate Ids. How would I go about making sure that they do not have duplicate ids, or at least somehow retrieving them? Let's say I want to get title view text from data_three liner layout. How would I do that?
the first question is why you don't use ListView instead and set values in your adapter? this is better.
But if you have to design your layout in this way, you have to at first get reference from your LinearLayout, the find your view by using LinearLayout reference, as following:
LinearLayout dataOne = findViewById(R.is.data_one);
TextView dataOneTitle = dataOne.findViewById(R.id.title);

How can I have one unique button in multiple components of a layout in android?

So I have an xml that consists of a linear layout containing a Button and a TextView like this:
<?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="100dp"
android:orientation="vertical">
<Button
android:id="#+id/btnCell"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingLeft="40dp"
android:text="Button"
android:textColor="#color/blueText" />
<View
android:height="wrap_content"
android:width="wrap_content"
android:background="#drawable/Test"/>
</LinearLayout>
And I want to use this same layout inside other layouts in a different xml. I need the same button at every time, so I reuse it by including it in the two layouts (both layouts are in the same xml, but ones is hidden):
First one
<?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">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include layout="#layout/buttonLayout"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Second One:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include layout="#layout/buttonLayout"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
So I show the first layout and hide the second one at the beginning of the app , as the user moves within the interface, the layouts exchange so that the other one is shown and the first one hidden.
The thing is that I declare the Button in my java activity class like this:
btnCell = (Button) thirdView.findViewById(R.id.btnCell);
btnCell.setOnClickListener(this);
And implemented the listener.
#Override
public void onClick(View v) {
if (v == btnCell) {
System.out.println("entered if");
}
System.out.println("entered function");
}
The problem is that when I click the button when the first view is shown and the second hidden, the button works just fine, but when I unhide the second layout, hide the first one, and proceed to click the button, that should be the same as the first one but in a different layout, nothing happens. I searched and find out, that this happens because the id is assigned only to the button shown in the first layout because of view hierarchy, but not the one in the second layout. How can I make both buttons react to the same action, without declaring a new button in each layout but instead reusing it?
I have used this type of layout. you can create Id different for both and inflate that view and give different name so You can differentiate both thing.
<?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">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include android:id="+id/firstOne" layout="#layout/buttonLayout"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
android second one is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include android:id="+id/secondTwo" layout="#layout/buttonLayout"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The Problem is both the layout are include in same layout file and the id of that
button are same so whenever you click on any of the button at the same time event will fire on both button like both are clicked.
So, you have to give the different id for both the button I hope it works fine..
You can add a different Id for each included layout:
<include android:id="+id/layout_a" layout="#layout/buttonLayout"/>
and
<include android:id="+id/layout_b" layout="#layout/buttonLayout"/>
and then use two findViewById to reach them:
btnCellA = (Button)thirdView.findViewById(R.id.layout_a).findViewById(R.id.btnCell);
btnCellB = (Button)thirdView.findViewById(R.id.layout_b).findViewById(R.id.btnCell);

How to show warning/error if used resource id belongs to another activity layout

Is there a way to show some warning/error when Android resource id does not belong to layout inflated in Activity?
Following is simple example, but in more complex layouts it is much harder to track down such issues as they can only be found during run-time. I would like to be able to catch them at compile-time.
MainActivity initialization
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// how to prevent erroneous usage of R.id.text2 at compile time
TextView t = (TextView) findViewById(R.id.text2);
}
activity_main.xml
<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"
tools:context=".MainActivity">
<TextView android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
activity_second.xml
<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"
tools:context=".SecondActivity">
<TextView android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
I don't know about any Lint checks or similar which can do what you require. I'd make a feature request because it looks like a useful feature.
For the time being I'd use prefixes in identifiers. E.g.:
findViewById(act_main_text1);
findViewById(act_main_text2);
root.findViewById(fragment_preferences_username);
And so on. It won't raise the error/warning during the build stage, but it'll make your life easier as you'll always know which activity/fragment/view this particular id belongs to.

"linearLayout cannot be resolved or it is not a field" with AdMob instructions by Google for Android

I am trying to find a solution to my problem by an hour and I found some topics with my similar problem, but I don't understand how to resolve.
I was developing an app with Processing for Android and I wanted to try AdMob (just for learning, for now), so I followed instructions all over the net and now I am stuck.
To add ads in the app, I was following Google instructions to add the SDK of Play Service and to add banners, but I am stuck here:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
initPdService();
// Create an ad.
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId("ca-app-pu....83399");
// Add the AdView to the view hierarchy. The view will have no size
// until the ad is loaded.
LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
layout.addView(adView);
AdRequest adRequest = new AdRequest.Builder()
// .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
// .addTestDevice("INSERT_YOUR_HASHED_DEVICE_ID_HERE")
.build();
// Start loading the ad in the background.
adView.loadAd(adRequest);
}
The problem is that it give me "linearLayout cannot be resolved or it is not a field", and I don't know how to resolve. I think that the problem is in findViewById(R.id.linearLayout), since the error is at "linearLayout" and not "LinearLayout".
I am sure that a lot of people find this problem, so I think that is a common problem. I already added import android.widget.LinearLayout;at the top of the sketch, so I don't know what is the problem.
Other infos: it is targeting Android SDK 19, as I know that Play Services want at least API level 13.
EDIT:
Here is my [old] activity_main.xml found is /res/layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
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=".MainActivity" >
<android.support.v7.widget.Space
android:id="#+id/space1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/adView"
android:layout_marginTop="208dp"
android:layout_toRightOf="#+id/adView" />
<View
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
EDIT 2:
This is my new activity_main.xml, with linearLayout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
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=".MainActivity" >
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:orientation="horizontal" >
<android.support.v7.widget.Space
android:id="#+id/space1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/adView"
android:layout_marginTop="208dp"
android:layout_toRightOf="#+id/adView" />
<View
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
</LinearLayout>
</RelativeLayout>
You need to set your content view:
setContentView(R.layout.activity_main);
which you have commented out. Do you have an xml file "activity_main.xml" that contains the LinearLayout with an id, linearLayout?
If yout don't have a LinearLayout with the id linearLayout, you need to add one. Otherwise, it's trying to find a view (by id!) that doesn't exist. For example:
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:orientation="horizontal" >
...
</LinearLayout>
Your issue is that you are using Processing as a library on top of the Android SDK, and it doesn't have access to the layout files, as in Processing you create your screens programatically - it is similar to one big Canvas class for those that are familiar with Android and not Processing.
What the actual compilation error is saying is that the generated R.java file is not finding the compressed resources
I've never tried to add AdMob, but really i think your issue here is that you need to instantiate a LinearLayout programatically, not via XML - as again, you won't have access to that through the PDE.
EDIT:
just noticed that you are using Eclipse (and LibPd !!)... ok, so you can reach a layout
Can you show the code where you are importing Processing into the Activity ?

Categories

Resources