Android - Finding ID of view from inflated layout - java

I know there are lots of other answers on stackoverflow on the same thing but I can't seem to get it to work.
What I'm trying to do is find the ID of a view from an inflated layout. I want WV1 to load google.com when the button is clicked, you can see I'm using onClick from XML to do this.
public void ButtonClicked(View view)
{
View inflatedView = getLayoutInflater().inflate(R.layout.tab_content, null);
WV1 = (WebView) inflatedView.findViewById(R.id.tab1WV);
WV1.setWebViewClient(new InsideWebViewClient());
if (WV1.isShown()) {
WV1.requestFocus();
}
else{
}
if (WV1.isFocused()) {
WV1.loadUrl("http://www.google.com");
}
}
This is in the MainActivity, the webview (WV1) is in the other, inflated class.
Problem is, nothing happens at all...
I've been stuck on this for quite some time now, I appreciate all help given to me.. If there's any other information you require then just ask, thanks in advance!
--Edit--
In the MainActivity, theres tabhost and a button that creates new tabs. When new tabs are created the MainActivity inflates the second class file containing the webview, I can't get the mainactivity to find the webview from the inflated class. I dont know if this helps any more or not...

Check out this link:
Android - Add textview to layout when button is pressed
Where one of the answers does this:
mLayout.addView(createNewTextView(mEditText.getText().toString()));
where mLayout is a linear layout in the activity.
You'd have to add a view to one of your current layouts or start up an activity that opens up with a web view in it.

Alternative way to create webview :
Webview WV1 = new WebView(view.getContext);
WV1.setWebViewClient(new InsideWebViewClient());
if (WV1.isShown()) {
WV1.requestFocus();
}
else{
}
if (WV1.isFocused()) {
WV1.loadUrl("http://www.google.com");
}
}
Now add this to a view group
viewgroup.addchild(WV1);

You're not attaching it to anything. You need to either supply the parent when you inflate it, or call addView on the ViewGroup that should contain it.
public void ButtonClicked(View view){
View inflatedView = getLayoutInflater().inflate(R.layout.tab_content, (ViewGroup) findViewById(android.R.id.content));
WV1 = (WebView) inflatedView.findViewById(R.id.tab1WV);
WV1.setWebViewClient(new InsideWebViewClient());
if (WV1.isShown()) {
WV1.requestFocus();
}
if (WV1.isFocused()) {
WV1.loadUrl("http://www.google.com");
}
}
Or:
((ViewGroup)findViewById(android.R.id.content)).addChild(WV1);
Both of these will add your view at the end. You may need to add some layout attributes to get it to look like you want.

Related

How to know which Toggle Buttons are clicked from dynamically added view?

This is my first time with android programming and I got stuck.
Now I'm trying to add view dynamically which contains toggle buttons, and edittext. However, whenever I select toggle button, options I created only works on last created view.
Options are simple. There are two toggle buttons and they can be clicked mutually exclusive
example
which means whenever I add new views such as B and C in above, the options are only worked on C while not in B. How can I make it to work on every view?
public void onAddField(View v){
LayoutInflater inflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView=inflater.inflate(R.layout.data_gledger_add_new,null);
tbg_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_gledger);
tbc_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_credit);
if(create_box<4){
csl.addView(rowView,csl.getChildCount()-1);
Log.d("create_box",String.valueOf(create_box));
create_box++;
}
else{
Log.d("create_box","full");
create_box=4;
}
tbg_add.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(tbg_add.isChecked()){
get_add_cla="menu1";
tbg_add.setTextColor(getResources().getColor(R.color.color_white));
tbc_add.setChecked(false);
tbc_add.setTextColor(getResources().getColor(R.color.color_black));
}
else{
get_add_cla="";
tbg_add.setTextColor(getResources().getColor(R.color.color_black));
}
}
});
//대변 선택
tbc_add.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(tbc_add.isChecked()){
get_add_cla="menu2";
tbc_add.setTextColor(getResources().getColor(R.color.color_white));
tbg_add.setChecked(false);
tbg_add.setTextColor(getResources().getColor(R.color.color_black));
}
else{
get_add_cla="";
tbc_add.setTextColor(getResources().getColor(R.color.color_black));
}
}
});
}
I forgot to mention that views are added by clicking button.
android:onClick="onAddField"
The problem almost certainly stems from the fact that you are re-using instance fields (tbg_add and tbc_add) as add new views dynamically.
tbg_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_gledger);
tbc_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_credit);
Because you are re-assigning these fields and also referencing them from the click listeners, you'll always be referencing the most recently created toggle buttons.
Change these to be local variables and everything should work fine.
ToggleButton ledger=(ToggleButton)rowView.findViewById(R.id.add_toggle_gledger);
ToggleButton credit=(ToggleButton)rowView.findViewById(R.id.add_toggle_credit);
Unrelated to your problem, but also something you should fix, is the fact that you're passing null as the second parameter to your inflate() call:
final View rowView=inflater.inflate(R.layout.data_gledger_add_new,null);
When you pass null in this manner, the system won't have any ability to correctly handle the LayoutParams (anything starting with android:layout_ in the xml file) for the newly-inflated view.
You know that you're going to wind up adding the rowView to your csl view, so you should pass that as the second parameter. Once you do that, you also have to pass false as a third parameter to make sure that the inflate() call actually returns the rowView and not its new parent (csl).
final View rowView=inflater.inflate(R.layout.data_gledger_add_new, csl, false);

Cant set text to EditText in DialogFragment

I have a button in listview row that when I click on it I want a dialogFragment to be open and set the text of an edit text (that located inside the dialogFragment) to some String.
The problem is: the app shut down when it comes to the line of the settext method.
This is the code I use to open the dialogFragment and set text to it.
public void onClick(View v) {
FragmentManager manager = getFragmentManager();
View parentRow = (View) v.getParent();
ListView listView = (ListView) parentRow.getParent();
final int position = listView.getPositionForView(parentRow);
TrempData data = adapter.getItem(position); //from here im getting the data that i want to set to the edit text.
Addtremp trempDialog = new Addtremp();
trempDialog.show(manager, "Addtremp");
trempDialog.from.setText(data.get_from());
trempDialog.to.setText(data.get_to());
trempDialog.date.setText(data.get_date());
trempDialog.time.setText(data.get_time());
trempDialog.extra.setText(data.get_extras());
}
Hope someone could help me.
Thanks.
Your App will surely crash due to NullPointerException. Because you are trying to set data on UI which is not rendered yet.
What steps should follow?
Pass data to DialogFragment which is going to display on UI in a form of arguments.
Create callback which will inform you when UI is rendered on Dialog. Check this Callback to a Fragment from a DialogFragment
. On getting listener you could set data on your UI components.
Personally I prefer solution1 and for that you should read passing argument to DialogFragment

Reloading android view in a fragment

I'm using Android Eclipse while working on a project where the user can save and upload notes with images.
I have a fragment which holds a textview and some thumbnail images. The user can add additional images by using the camera and they can remove images by viewing(clicking) an image (in a separate activity) and deleting it.
My problem is with refreshing the layout of the fragment to reflect a deleted image. Currently the following function is being called to deal with this:
public ViewGroup removeNoteImageFromView(String location) {
List<String> imageLinks = new ArrayList<String>();
for (String string : imageLocations) {
if (string.equalsIgnoreCase(location)) {
break;
}
imageLinks.add(string);
}
//REMOVE ALL THE IMAGEVIEWS from the Linear Layout
LinearLayout linear = (LinearLayout) rootView.findViewById(R.id.imageContainer);
if (linear.getChildCount() != 0) {
linear.removeAllViewsInLayout();
linear.refreshDrawableState();
linear.postInvalidate();
}
imageLocations.addAll(imageLinks);
//Add them all back from the new array
String root = Environment.getExternalStorageDirectory().toString();
for (String string : imageLinks) {
Bitmap myBitmap = BitmapFactory.decodeFile((new File(root +"/saved_images/"+string)).getAbsolutePath());
addImage(myBitmap);
}
return linear;
}
All this code does is hide all thumbnails which is called by linear.removeAllViewsInLayout(). However the following two line are what I thought would reload the layout on screen but they appear to have no effect whatsoever.
Please note I have tried linear.invalidate() as well as postInvalidate and still get nothing.
The correct image is deleted from the device as this is dealt with elsewhere so when I go back to this fragment by reselecting it in the menu everything is displayed correctly.
Replace this:
linear.refreshDrawableState();
linear.postInvalidate();
With this:
linear.requestLayout();
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Your code is here...
// for refresh view use..
convertView.invalidate();
}
Ok so I finally got it!
I feel a bit stupid as the code works fine but the root path was incorrect so it wasn't finding the images to add back into the view.
Thank you for all the responses and help. Sorry for my newbieness (I've only been properly using Java for a couple of weeks).

Android: Cannot get a clickable ListView header/footer

I'm trying to set a header and footer in my list view that are clickable buttons. The problem is that the OnClickListener isn't responding to anything and I can't figure out what I'm doing wrong.
$ View header = getLayoutInflater().inflate(R.layout.header_layout, null, true);
getListView().addHeaderView(header);
myAdapter = new myAdapter(this);
header.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do what I want when i click it
}
});
Update
The best solution I ultimately came up with was adding a separate button to the header layout, and then doing it like this:
View header = getLayoutInflater().inflate(R.layout.header_layout, null);
Button headerButton = (Button)header.findViewById(R.id.header_button);
getListView().addHeaderView(header);
headerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// My Click Stuff
}
});
You need to handle the click in the ListView's onItemClick. Simply check if that's the first or last item in the adapter and handle the clicks that way. You need to treat it as an item in the ListView.
I see a few issues:
when inflating the header, use getListView() as the second parameter (root, where you have null now)l
should the header be a View or a ViewGroup? I've ended up using ViewGroup in these situations.
finally -- perhaps you should be setting the click listener on the button in the header instead of the header itself?
There is a way more easier solution:
Just set a "OnClickListener" to the applied View:
View view = inflater.inflate(R.layout.xxx, null);
view.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
//do something
}
});
Very easy thing which solved it!
Example with a footer:
mYourListView.addFooterView(footer, null, true);
Then in the OnItemClickListener you can check:
#Override
public void onItemClick(AdapterView<?> parent,
View view, final int position, final long id) {
if (id != -1) {
// do whatever you do with list items
} else {
// do what you need after the footer been clicked
}
(If you need to handle and the header and the footer click, check position - 0 for the header and [adapter.getCount() - 1] for the footer)
This approach will provide the same visual effect while footer click as if the list item been clicked. (But if you do not need that effect just add OnClickListener to the footer and it will intercept all footer clicks)
i think the listview and buttons are fighting for focus and your listview is winning.
you'll have to use a onTouchListener for the buttons.
There is one more alternative and its to set the following on the footer. There is another method overload created but it did not come up in the docs, i had to check online documentation:
mylistView.addFooterView(footerView, null, false);
where false tells the footer its not selectable. I tested this myself and the buttons inside the footer respond to touches now. I hope this an acceptable answer.
What worked for me:
When inflating the header view, before adding it to the listview, I then used that view to get the subview and add a click listener on it
myHeaderView.findViewById(R.id.myButton).setOnClickListener(new OnClickListener() { ... } );
also, when I added it to the listView, I used the overloaded constructor with the third variable set to true
mListView.addHeaderView(myHeaderView, null, true);

Updating Android Tab Icons

I have an activity that has a TabHost containing a set of TabSpecs each with a listview containing the items to be displayed by the tab. When each TabSpec is created, I set an icon to be displayed in the tab header.
The TabSpecs are created in this way within a setupTabs() method which loops to create the appropriate number of tabs:
TabSpec ts = mTabs.newTabSpec("tab");
ts.setIndicator("TabTitle", iconResource);
ts.setContent(new TabHost.TabContentFactory(
{
public View createTabContent(String tag)
{
...
}
});
mTabs.addTab(ts);
There are a couple of instances where I want to be able to change the icon which is displayed in each tab during the execution of my program. Currently, I am deleting all the tabs, and calling the above code again to re-create them.
mTabs.getTabWidget().removeAllViews();
mTabs.clearAllTabs(true);
setupTabs();
Is there a way to replace the icon that is being displayed without deleting and re-creating all of the tabs?
The short answer is, you're not missing anything. The Android SDK doesn't provide a direct method to change the indicator of a TabHost after it's been created. The TabSpec is only used to build the tab, so changing the TabSpec after the fact will have no effect.
I think there's a workaround, though. Call mTabs.getTabWidget() to get a TabWidget object. This is just a subclass of ViewGroup, so you can call getChildCount() and getChildAt() to access individual tabs within the TabWidget. Each of these tabs is also a View, and in the case of a tab with a graphical indicator and a text label, it's almost certainly some other ViewGroup (maybe a LinearLayout, but it doesn't matter) that contains an ImageView and a TextView. So with a little fiddling with the debugger or Log.i, you should be able to figure out a recipe to get the ImageView and change it directly.
The downside is that if you're not careful, the exact layout of the controls within a tab could change and your app could break. Your initial solution is perhaps more robust, but then again it might lead to other unwanted side effects like flicker or focus problems.
Just to confirm dominics answer, here's his solution in code (that actually works):
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
if (TAB_MAP.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
} else if (TAB_LIST.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
}
}
});
Of course it's not polished at all and using those direct indices in getChildAt() is not nice at all...
See my post with code example regarding Customized Android Tabs.
Thanks
Spct
This is what I did and it works for me. I created this function in the activity that extends from TabBarActivity
public void updateTab(int stringID) {
ViewGroup identifyView = (ViewGroup)getTabWidget().getChildAt(0);
TextView v = (TextView)identifyView.getChildAt(identifyView.getChildCount() - 1);
v.setText(stringID);
}
You can modify this function to change the image instead of text or you can change both, also you can modify this to get any tab child. I was particularly interested in modifying the text of the first tab at runtime.
I called this function from the relevant activity using this call
getParent().updateTab(R.string.tab_bar_analyze);
Try This:
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
if (TAB_MAP.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
} else if (TAB_LIST.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
}
}
});

Categories

Resources