Cannot Combine Custom Title With Other Title Features - android

I understand what the error is telling me, but I have no idea what I could be using that it considers title features that I'm trying to combine with Custom Title.
inspection_title.axml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/inspectionTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:marqueeRepeatLimit="-1"/>
LiftInspection.cs
[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]
public class LiftInspection : ExpandableListActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
string callInfo = Intent.GetStringExtra("CallInfo");
RequestWindowFeature(WindowFeatures.CustomTitle);
SetContentView(Resource.Layout.LiftInspection);
Window.SetFeatureInt(WindowFeatures.CustomTitle, Resource.Layout.inspection_title);
TextView title = (TextView) FindViewById(Resource.Id.inspectionTitle);
title.Text = callInfo;
}
There is no additional title customization in the manifest or anything. What could possibly be combining with the CustomTitle to generate this exception?

check in AndroidManifest.xml if your theme's name is "AppTheme", if so try to change it to any other, it's strange but it helped me

try this way:
final Window window = getWindow();
boolean useTitleFeature = false;
if(window.getContainer() == null) {
useTitleFeature = window.requestFeature(Window.FEATURE_CUSTOM_TITLE);
}
SetContentView(Resource.Layout.LiftInspection);
if (useTitleFeature) {
window.setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.inspection_title);
}

Related

Visible password with TextInputLayouts passwordToggleEnabled

I am using a TextInputLayout with the new function from the Support Library: passwordToggleEnabled. This gives a nice "eye"-icon that lets the user toggle password visibility on and off.
My question is if there is a way to use this functionality but start with password visible?
My xml:
<android.support.design.widget.TextInputLayout
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true">
<EditText
android:id="#+id/password_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/prompt_password"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
The toggle looks similar to this:
I have not found a way to do this in xml, and not a way to manually toggle the visibility after the view is rendered. If I set the input type of the EditText to textVisiblePassword, the toggle is not shown. If I do it in code using for instance mPasswordEditText.setTransformationMethod(null); the password is shown but the toggle is gone and the user can't hide the password again. I know I can do it all manually but just wondering if I can make it work with the new magic toggle
Easiest way is below Another solution is at last of this answer
private void setupPasswordToggleView() {
final TextInputLayout textInputLayout = mRootView.findViewById(R.id.password);
// You can skip post-call and write directly the code which is inside run method.
// But to be safe (as toggle-view is child of TextInputLayout, post call
// has been added.
textInputLayout.post(new Runnable() {
#Override
public void run() {
CheckableImageButton passwordToggleView = textInputLayout.findViewById(R.id.text_input_password_toggle);
// passwordToggleView.toggle(); // Can not use as restricted to use same library group
// passwordToggleView.setChecked(true); // Can not use as restricted to use same library group
passwordToggleView.performClick();
}
});
}
Now let me explain the answer
While looking into code of TextInputLayout.java I found that, there is a layout design_text_input_password_icon.xml which is being added to TextInputLayout.java. Below is that code
private void updatePasswordToggleView() {
if (mEditText == null) {
// If there is no EditText, there is nothing to update
return;
}
if (shouldShowPasswordIcon()) {
if (mPasswordToggleView == null) {
mPasswordToggleView = (CheckableImageButton) LayoutInflater.from(getContext())
.inflate(R.layout.design_text_input_password_icon, mInputFrame, false);
mPasswordToggleView.setImageDrawable(mPasswordToggleDrawable);
mPasswordToggleView.setContentDescription(mPasswordToggleContentDesc);
mInputFrame.addView(mPasswordToggleView); // << HERE IS THAT
.........
}
Now next target was to find design_text_input_password_icon.xml and lookup id of the toggle view. So found the layout design_text_input_password_icon.xml here and it has written as
18<android.support.design.widget.CheckableImageButton
19 xmlns:android="http://schemas.android.com/apk/res/android"
20 android:id="#+id/text_input_password_toggle"
21 android:layout_width="wrap_content"
22 android:layout_height="wrap_content"
23 android:layout_gravity="center_vertical|end|right"
24 android:background="?attr/selectableItemBackgroundBorderless"
25 android:minHeight="48dp"
26 android:minWidth="48dp"/>
I found the id text_input_password_toggle of that view and now everything was easy to just find that view in it's viewgroup and perform action on that.
Another solution would be to iterate childs of TextInputLayout and check if it is CheckableImageButton and then perform click on it. By this way there would not be dependancy on id of that view and if Android changes the id of view, our solution will still work. (Although they do not change id of a view in normal cases).
private void setupPasswordToggleViewMethod2() {
final TextInputLayout textInputLayout = mRootView.findViewById(R.id.password);
textInputLayout.post(new Runnable() {
#Override
public void run() {
View toggleView = findViewByClassReference(textInputLayout, CheckableImageButton.class);
if (toggleView != null) {
toggleView.performClick();
}
}
});
}
Where findViewByClassReference(View rootView, Class<T> clazz) original utility class is defined as below
public static <T extends View> T findViewByClassReference(View rootView, Class<T> clazz) {
if(clazz.isInstance(rootView)) {
return clazz.cast(rootView);
}
if(rootView instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) rootView;
for(int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
T match = findViewByClassReference(child, clazz);
if(match != null) {
return match;
}
}
}
return null;
}
With the Material Components Library (1.1.0 , 1.2.0-beta01, 1.3.0-alpha01) to start with a visible password just use:
<com.google.android.material.textfield.TextInputLayout
app:endIconMode="password_toggle"
/>
and in your code:
textInputLayout.getEditText().setTransformationMethod(null);
If you want to return to the default behavior:
textInputLayout.getEditText()
.setTransformationMethod(PasswordTransformationMethod.getInstance());
Just removing android:inputType="textPassword" worked for me
One of the ways is, we can search CheckableImageButton from TextInputLayout, and then programmatically perform onClick on it, based on the password visibility status of EditText.
Here's the code snippet.
private CheckableImageButton findCheckableImageButton(View view) {
if (view instanceof CheckableImageButton) {
return (CheckableImageButton)view;
}
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0, ei = viewGroup.getChildCount(); i < ei; i++) {
CheckableImageButton checkableImageButton = findCheckableImageButton(viewGroup.getChildAt(i));
if (checkableImageButton != null) {
return checkableImageButton;
}
}
}
return null;
}
//...
if (passwordEditText.getTransformationMethod() != null) {
CheckableImageButton checkableImageButton = findCheckableImageButton(passwordTextInputLayout);
if (checkableImageButton != null) {
// Make password visible.
checkableImageButton.performClick();
}
}
I was able to get it to start in clear-text mode with the following bit of code. Basically, I had to find the right View using the content description.
If they provided a setter method for mPasswordToggledVisibility that would make things a lot easier...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextInputLayout til = findViewById(R.id.password);
CharSequence cs = til.getPasswordVisibilityToggleContentDescription();
ArrayList<View> ov = new ArrayList<>();
til.findViewsWithText(ov, cs,View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if( ov.size() == 1 ) {
Checkable c = (Checkable)ov.get(0);
// As far as I can tell the check for "isChecked" here isn't needed,
// since it always starts unchecked by default. However, if you
// wanted to check for state, you could do it this way.
if( c != null && !c.isChecked()) {
ov.get(0).performClick();
}
}
}
try this
if (inputEditText.getTransformationMethod() == null) {
inputEditText.setTransformationMethod(new PasswordTransformationMethod());
} else {
inputEditText.setTransformationMethod(null);
}
inputEditText.setSelection(inputEditText.getText().length());
You can use the bellow code:
TextInputLayout yourTextInputLayoutId = findViewById(R.id.yourTextInputLayoutId);
FrameLayout frameLayout = (FrameLayout) (yourTextInputLayoutId).getChildAt(0);
CheckableImageButton checkableImageButton = (CheckableImageButton) frameLayout.getChildAt(1);
checkableImageButton.performClick();
Here yourTextInputLayoutId is your TextInputLayout id from xml.
To start with Password visible,
Do not include
android:inputType="textPassword"
In
<com.google.android.material.textfield.TextInputEditText>
....
</com.google.android.material.textfield.TextInputEditText>
You can add in your xml file in TextInputLayout
passwordToggleEnabled="true"
passwordToggleDrawable=""#drawable/show_password_selector"
and make your show_password_selector.xml
this will look the same as the picture you sent
You can use:
yourEditText.setTransformationMethod(new PasswordTransformationMethod());
To re-show the readable password, just pass null as transformation method:
yourEditText.setTransformationMethod(null);
so user can hide it again.

Why isn't Gravity taking effect on my buttons?

I'm using Signature Pad and I would like to move the buttons that I add on top of that view using Gravity but nothing happens, I have tried several flags and they all look the same. I also tried to add the signature view to the layout at the end of the method but that didn't change anything either.
The activity:
[Activity(Label = "Authorize Buyin", ScreenOrientation = Android.Content.PM.ScreenOrientation.Landscape)]
public class Sign : Activity
{
LinearLayout layout;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.sign_dialog);
layout = FindViewById<LinearLayout>(Resource.Id.layoutSign);
CreateSignaturePad();
}
private void CreateSignaturePad()
{
var signature = new SignaturePadView(this)
{
StrokeWidth = 3f,
BackgroundColor = Android.Graphics.Color.White,
StrokeColor = Android.Graphics.Color.Black,
};
layout.AddView(signature,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent));
/* Add Clear Button */
Button btnClear = new Button(this) { Text = "Borrar" };
signature.AddView(btnClear);
/* Add Authorize Button */
Button btnAuthorize = new Button(this) { Text = "Authorize" };
btnAuthorize.Gravity = GravityFlags.Center;
signature.AddView(btnAuthorize);
}
}
The layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layoutSign"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="2dp">
</LinearLayout>
SignatureView is inherited from RelativeLayout. signature is SignatureView.
This is how I finally solved it:
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WrapContent,
RelativeLayout.LayoutParams.WrapContent);
lp.AddRule(LayoutRules.AlignParentBottom);
Button btnAuthorize = new Button(this) { Text = "Authorize" };
btnAuthorize.LayoutParameters = lp;
btnAuthorize.Click += BtnAuthorize_Click;
signature.AddView(btnAuthorize);

Set OnClick Listener on Action Bar Title in Android

I am working on android application where I am using ActionBar so there one is navigation drawer icon to open it and title of ActionBar in ActionBar. I want to set a click listener on title of ActionBar such that it start a new Activity and set click listener different on navigation drawer icon to open navigation drawer menu.
I achieved a click on navigation drawer icon but when I click on title of ActionBar title also then it open the navigation drawer menu. Is there any way to set different click listener on title of ActionBar.
Thanks in advance.
Try adding this code under the onCreate() function. This will grab the resource the action bar title is under, and assign it an id you can use to add an OnClickListener to. Let me know how it goes!
final int abTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
findViewById(abTitleId).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do something
}
});
You could use a custom layout for the title and assign a listener to it:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getActionBar();
if (actionBar != null) {
// Disable the default and enable the custom
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
View customView = getLayoutInflater().inflate(R.layout.actionbar_title, null);
// Get the textview of the title
TextView customTitle = (TextView) customView.findViewById(R.id.actionbarTitle);
// Change the font family (optional)
customTitle.setTypeface(Typeface.MONOSPACE);
// Set the on click listener for the title
customTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.w("MainActivity", "ActionBar's title clicked.");
}
});
// Apply the custom view
actionBar.setCustomView(customView);
}
}
actionbar_title.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<TextView
android:id="#+id/actionbarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="#string/app_name"/>
</LinearLayout>
I think Simas's answer is the best one, but here's a hacky version in case you prefer that.
ViewTools.findActionBarTitle(getWindow().getDecorView()).setOnClickListener(...);
This one should be universal in that it works with:
stock Android ActionBar
Theme.AppCompat support ActionBar
v21-style setActionBar
use <Toolbar android:id="#+id/action_bar"
or pass in the inflated Toolbar as root
v21-style setSupportActionBar
use <android.support.v7.widget.Toolbar android:id="#id/action_bar"
or pass in the inflated Toolbar as root
custom Toolbar implementations may need a little adjustment,
but then you could encapsulate this in that custom class.
Though I only tested with support:v22.
/** #param root usually Activity.getWindow().getDecorView() or your custom Toolbar */
public static #Nullable View findActionBarTitle(#NonNull View root) {
return findActionBarItem(root, "action_bar_title", "mTitleTextView");
}
/** #param root usually Activity.getWindow().getDecorView() or your custom Toolbar */
public static #Nullable View findActionBarSubTitle(#NonNull View root) {
return findActionBarItem(root, "action_bar_subtitle", "mSubtitleTextView");
}
private static #Nullable View findActionBarItem(#NonNull View root,
#NonNull String resourceName, #NonNull String toolbarFieldName) {
View result = findViewSupportOrAndroid(root, resourceName);
if (result == null) {
View actionBar = findViewSupportOrAndroid(root, "action_bar");
if (actionBar != null) {
result = reflectiveRead(actionBar, toolbarFieldName);
}
}
if (result == null && root.getClass().getName().endsWith("widget.Toolbar")) {
result = reflectiveRead(root, toolbarFieldName);
}
return result;
}
#SuppressWarnings("ConstantConditions")
private static #Nullable View findViewSupportOrAndroid(#NonNull View root, #NonNull String resourceName) {
Context context = root.getContext();
View result = null;
if (result == null) {
int supportID = context.getResources().getIdentifier(resourceName, "id", context.getPackageName());
result = root.findViewById(supportID);
}
if (result == null) {
int androidID = context.getResources().getIdentifier(resourceName, "id", "android");
result = root.findViewById(androidID);
}
return result;
}
#SuppressWarnings("unchecked")
public static <T> #Nullable T reflectiveRead(#NonNull Object object, #NonNull String fieldName) {
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (T)field.get(object);
} catch (Exception ex) {
Log.w("HACK", "Cannot read " + fieldName + " in " + object, ex);
}
return null;
}
If you are using Toolbar with support v7:21.
Check out the following code:
Field titleField = Toolbar.class.getDeclaredField("mTitleTextView");
titleField.setAccessible(true);
TextView barTitleView = (TextView) titleField.get(mToolbar);
barTitleView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
You can do this easily using Toolbar. Define toolbar in layout xml file as given below:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="?colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<TextView
android:id="#+id/toolbarTitle"
style="#style/TextAppearance.Widget.AppCompat.Toolbar.Title"
android:background="?attr/selectableItemBackground"
android:layout_width="wrap_content"
android:gravity="center_vertical"
android:layout_height="match_parent" />
</android.support.v7.widget.Toolbar>
Then you can set the listener in Activity using this code:
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
TextView toolbarTitle= (TextView) findViewById(R.id.toolbarTitle);
toolbarTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// DO SOMETHING HERE
}
});
If you want to use the currently existing ActionBar and not the Toolbar, use the following:
ActionBar actBar = getSupportActionBar();
if(actBar != null) {
actBar.setTitle(R.string.your_ab_title);
}
//Set actions to take when the AB is clicked
Toolbar ab = findViewById(R.id.action_bar);
if(ab != null){
for (int i= 0; i < ab.getChildCount(); i++){
View child = ab.getChildAt(i);
if(child instanceof TextView || child instanceof ImageView) {
child.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String url = "http://www.HoverDroids.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
}
}
}
If you know the actual text that is in your Title, and you are reasonably sure that no other TextView on the screen shares that title, you can use a recursive View tree search to find it.
This is a great solution because it doesn't require reflection of internal knowledge of how to Toolbar is constructed, and gives you direct access to the TextView.
#Nullable
public static TextView findTextViewWithText(#Nullable View toCheck, String toFind) {
if (toCheck instanceof TextView) {
String foundText = ((TextView) toCheck).getText().toString();
if (foundText.equals(toFind)) {
return (TextView) toCheck;
}
} else if (toCheck instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) toCheck).getChildCount(); i++) {
TextView found = findTextViewWithText(((ViewGroup) toCheck).getChildAt(i), toFind);
if (found != null) {
return found;
}
}
}
return null;
}
The most reliable view to call this on is the decor view but feel free to experiment what works best for your purposes, your mileage may vary.
View found = findTextViewWithText(
getActivity().getWindow().getDecorView(), "My Title");
if (found != null) {
// Do something, like set a click listener
}
I know its too late, but for or those who use SupportActionBar like this and still have not found a clean solution:
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
For the default configuration without logo and custom views, 1st item (index 0) will be the Home/Back ImageView, 2nd item will be our Title TextView and 3rd item will be the OptionMenu Imageview.
Getting child at index 1 would return title. Adding an OnClickListener to the child will make it work like a chram:
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.getChildAt(1).setOnClickListener(v -> {
// title is clicked, call ur function here
// can also verify that the view is title itself by converting it to textview
try {
String title = ((TextView)v).getText().toString();
// title will be your activity title
} catch (Exception e) {
e.printStackTrace();
// if you got an exception, the view is not title.
// Check changing the index, in case you have custom views in the toolbar.
}
});
You can do this easily using Toolbar. Define toolbar in layout xml file as given below:
<android.support.v7.widget.Toolbar
android:id="#+id/MainActivityToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/app_name"
android:textSize="30sp"
tools:ignore="RelativeOverlap"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
/>
<Button
android:id="#+id/LogOutButton"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:text="#string/logout" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
Then you can set the listener in Activity using this code:
setSupportActionBar((Toolbar) findViewById(R.id.MainActivityToolbar));
logOutButton = findViewById(R.id.LogOutButton);
logOutButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//define your function for logout or something else
LogOut();
}
});
I know it's very late to comment here but I came across this question when I searched for how to add OnClick for Action bar title.
Below is what I found and worked for me, hope it will help someone like me.
I wrote it for a fragment in my app.
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
actionBar.setTitle("");
((AppCompatActivity) getActivity()).setSupportActionBar((Toolbar) getActivity().findViewById(R.id.toolbar));
TextView toolbarTitle = (TextView) getActivity().findViewById(R.id.toolbarTitle);
toolbarTitle.setText("New title");
toolbarTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Action bar title clicked
}
});
actionBar.show();

How to set Id of dynamic created layout?

I want to give ID to some views (textview ,imageview etc) in a layout that is programmetically created.
So what is the best way to set ID.
You create an ids.xml file and place all your required ids in it as below
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="layout1" />
<item type="id" name="layout2" />
<item type="id" name="layout3" />
</resources>
Now for your dynamically created layouts or views you can use these ids as below
new_layout1.setId(R.id.layout1);
new_view2.setId(R.id.layout2);
new_layout3.setId(R.id.layout3);
I hope it may help you.
Google finally realized the need of generating unique IDs for programmatically created views...
From API level 17 and above, one can use View.generateViewId() like this:
view.setId(View.generateViewId());
For apps targeting API level 16 or lower, use ViewCompat.generateViewId() instead:
view.setId(ViewCompat.generateViewId());
create folder res/values/ids.xmland
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="refresh" type="id"/>
<item name="settings" type="id"/>
</resources>
in Activity class call like this
ImageView refreshImg = new ImageView(activity);
ImageView settingsImg = new ImageView(activity);
refreshImg.setId(R.id.refresh);
settingsImg .setId(R.id.settings);
This wont work:
layout.setId(100);
But, this will:
int id=100;
layout.setId(id);
also, this one too (credit: Aaron Dougherty):
layout.setId(100+1);
For compatibility purposes use: ViewCompat.generateViewId()
If you are putting a group of components repeatedly into a layout programmatically like below:
<LinearLayout>
<ImageView>
<TextView>
<Button>
<ImageView>
<TextView>
<Button>
<ImageView>
<TextView>
<Button>
...
</LinearLayout>
then,you can use for loop and give ids accordingly:
for(int i=0;i<totalGroups;i++)
{
ImageView img;
TextView tv;
Button b;
... // set other properties of above components
img.setId(i);
tv.setId(i);
b.setId(i);
... //handle all events on these components here only
... //add all components to your main layout
}
Or if just one group of component you want to add,you can use any integer number which is large and don't conflict with other component's ids in Resources.It won't be much conflicting.
I went about it in a different way.
Created my own R.id HashMap.
Than used the value for the view.setID() part.
String is the id, Integer its value
Private HashMap<String, Integer> idMap= new HashMap<String, Integer>();
private int getRandomId(){
boolean notInGeneralResourses = false;
boolean foundInIdMap = false;
String packageName = mainActivity.getPackageName();
Random rnd = new Random();
String name ="";
//Repaet loop in case random number already exists
while(true) {
// Step 1 - generate a random id
int generated_id = rnd.nextInt(999999);
// Step 2 - Check R.id
try{
name = mainActivity.getResources().getResourceName(generated_id);
}catch(Exception e){
name = null;
}
notInGeneralResourses = false;
if (name == null || !name.startsWith(packageName)) {
notInGeneralResourses = true;
}else{
notInGeneralResourses = false;
localLog("Found in R.id list.");
}
// Step 3 - Check in id HashMap
if(notInGeneralResourses){
List<Integer> valueList = new ArrayList<Integer>(idMap.values());
foundInIdMap = false;
for (Integer value : valueList) {
if (generated_id == value) {
foundInIdMap = true;
localLog("Found in idMAp.");
}
}
}
// Step 4 - Return ID, or loop again.
if (!foundInIdMap) {
localLog("ID clear for use. "+generated_id);
return generated_id;
}
}
}
and to set:
String idName = "someName";
int generated_R_id = getRandomId();
idMap.put(idName,generated_R_id);
someView.setId(idMap.get(idName));
Now, at any point you can just:
ImageView test = (ImageView)
mainActivity.findViewById(idMap.get("somName"));
and to test it -
test.setImageResource(R.drawable.differentPic);
P.S. I've written it like this for ease of explain.
Obviously it can be written better andmore compact.
Try this code!
This should help give an idea.
activity_prac_main.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:text="#string/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/display_txt"
android:textStyle="bold"
android:textSize="18sp"
android:textAlignment="center"
android:layout_gravity="center_horizontal"/>
<GridLayout
android:id="#+id/my_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rowCount="4">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/linear_view">
<Button
android:text="#string/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/my_btn"
android:layout_gravity="center_horizontal"/>
<TextView
android:text="#string/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/my_txt"
android:textSize="18sp"
/>
</LinearLayout>
</GridLayout>
</LinearLayout>
here's the rest of code
public class AnotherActivity extends AppCompatActivity {
private int count = 1;
List<Integer> gridArray;
private TextView myDisplayText;
#Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gridArray = new ArrayList<>();
gridArray.add(Integer.valueOf(1));
setContentView(R.layout.activity_prac_main);
findViews();
}
private void findViews(){
GridLayout gridLayout = (GridLayout)findViewById(R.id.my_grid);
gridLayout.setColumnCount(4);
LinearLayout linearLayout = (LinearLayout) gridLayout.findViewById(R.id.linear_view);
linearLayout.setTag("1");
Button myButton = (Button) linearLayout.findViewById(R.id.my_btn);
myButton.setTag("1");
TextView myText = (TextView) linearLayout.findViewById(R.id.my_txt);
myText.setText("1");
myDisplayText = (TextView) findViewById(R.id.display_txt);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView txt = (TextView) view;
myDisplayText.setText("PRESS " + txt.getTag().toString());
if(count < 24) {
createView();
}
else{
dialogBox();
}
}
});
}
private void createView(){
LinearLayout ll = new LinearLayout(this);
ll.setId(Integer.valueOf(R.id.new_view_id));
ll.setTag(String.valueOf(count+1));
Button newBtn = createButton();
newBtn.setId(Integer.valueOf(R.id.new_btn_id));
newBtn.setTag(String.valueOf(count+1));
TextView txtView = createText();
txtView.setId(Integer.valueOf(R.id.new_txt_id));
txtView.setTag(String.valueOf(count+1));
txtView.setText(String.valueOf(count+1));
GridLayout gridLayout = (GridLayout)findViewById(R.id.my_grid);
ll.addView(newBtn);
ll.addView(txtView);
ll.setOrientation(LinearLayout.VERTICAL);
gridLayout.addView(ll);
count++;
}
private Button createButton(){
Button myBtn = new Button(this);
myBtn.setText(R.string.button_send);
myBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView txt = (TextView) view;
myDisplayText.setText("PRESS " + txt.getTag().toString());
if(count < 24) {
createView();
}
else{
dialogBox();
}
}
});
return myBtn;
}
public void dialogBox() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("GRID IS FULL!");
alertDialogBuilder.setPositiveButton("DELETE",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
GridLayout gridLayout = (GridLayout)findViewById(R.id.my_grid);
gridLayout.removeAllViews();
count = 0;
createView();
}
});
alertDialogBuilder.setNegativeButton("CANCEL",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
private TextView createText(){
TextView myTxt = new TextView(this);
myTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
return myTxt;
}
}
As you can see ids were created in res -> values -> ids file.
when creating views dynamically id is the same for the views.
Each TextView share same id. Each Button share same id. each layout share same id.
Ids are only important to access the contents of views.
However the Tag is what makes each view unique to each other.
Hope this helps you out!
All you need to do is call ViewCompat.generateViewId()
For Example:
val textView = TextView(this)
textView.text = "Hello World"
textView.setLayoutParams(ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
textView.id = ViewCompat.generateViewId()
You can define your Ids as resources and then use setId() of the view to set it.
In a xml file, define the ID's like:
<resources>
<item type="id">your id name</item>
</resources>
then, use in the java file as..
layout.setId(R.id.<your id name>)

Could you give me a short Android code to create this?

http://habrastorage.org/storage/211878a0/14f474e6/bc73d2e8/a709e893.gif
how can I utilize the Toast object to ask a question?
I searched around but was not able to find how to make a Toast object ask a question
Thanks a lot Stack Overflow
here is a sample:
the solution is using an alert dialog with a layout that has a label and a text box.
public Dialog create()
{
LayoutInflater li = LayoutInflater.from(this._context);
this._view = li.inflate(R.layout.prompt_dialog, null);
AlertDialog ad = new AlertDialog.Builder(this._context).create();
ad.setView(this._view);
if(this._title != null)
{
ad.setTitle(this._title);
}
if(this._icon != 0)
{
ad.setIcon(this._icon);
}
TextView tv1 = (TextView)this._view.findViewById(R.id.prompt_dialog_message);
tv1.setText(this._message);
ad.setButton(DialogInterface.BUTTON_POSITIVE, _context.getString(R.string.ok), this);
ad.setButton(DialogInterface.BUTTON_NEUTRAL, _context.getString(R.string.cancel), this);
return ad;
}
I've used these in my Emergency Tools App And I didn't had any problems :)
Actually that's just a PreferenceActivity. Take a look at the JavaDoc for http://developer.android.com/reference/android/preference/PreferenceActivity.html
What you see is not a Toast notification.
It is a CustomDialog read more here
This is an EditTextPreference inside a PreferenceActivity
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mypref="http://schemas.android.com/apk/res/com.tneele.daynightlwp"
android:title="#string/settings_title"
android:key="daynightwallpaper_settings">
<EditTextPreference
android:dialogTitle="UserName" />
</PreferenceScreen>
PreferenceActivity:
public class MyPreferenceActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}

Categories

Resources