Access android custom ActionBar from Activity - android

I created a class that extends ActionBarActivity and displays a custom XML. That class is extended by almost all my activities.
I want to access an element of that custom XML from one of my activities. Let's say I want to change the background of item2 when I'm in Activity2.
In my activity's onCreate method, after setContentView, I tried:
View cView = getLayoutInflater().inflate(R.layout.custom_menu, null);
ImageButton rewards_link = (ImageButton) cView.findViewById(R.id.rewards_link);
rewards_link.setVisibility(View.GONE); // For test purpose
Even if the button id seems correct, the changes doesn't apply. Any ideas ?

If you are setting the custom view via getActionBar().setCustomView(R.layout.custom_menu); (or getSupportActionBar() for v21 of AppCompat), then you can access those views by using findViewById() directly as the view is part of your view hierarchy just like views added via setContentView():
ImageButton rewards_link = (ImageButton) findViewById(R.id.rewards_link);
rewards_link.setVisibility(View.GONE); // For test purpose

Use #getCustomView
View view =getSupportActionBar().getCustomView(); ImageButton imageButton =
(ImageButton)view.findViewById(R.id.action_bar_back); imageButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v){
// Your code here ...
}
});

Related

Defining from another xml file

I am creating an application that uses a navigation drawer. However, the navigation drawer layout or design that I am using is from a different XML file, not on my MainActivity. I have an image in the layout that I am using that I want to apply as SetOnClickListener on my MainActivity. But I have no idea how I can define the image that is in a separate XML file in my MainActivity.
in your case you have 2 different XML file(layout files)
main Activity
navigation drawer
each layout file must have an own java class to get access to view objects.
but if you don't have another java class for navigation drawer, use an LayoutInflater to inflate the XML layout to an view, then you can access an set the Listener to any of views you want
in main activity add:
LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
View rootView = li.inflate(R.layout.my_navigation_drawer_layout,null,false);
note* replace your layout file name with my_navigation_drawer_layout
now you can declare an image view and use findViewById from rootView we create earlier
final ImageView img = (ImageView) rootView.findViewById(R.id.myImageViewName)
now you can set listener to img :
img.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// write your code here!!!
}
});
What you want to do, is easy using <include> tag over the XML of the MainActivity class
<include
android:layout = "YOUR LAYOUT OF THE NAVIGATION"/>

Having problems setting up button of another layout

The problem is MainActivity starts with a setContentView with a layout.xml. We can add buttons or anything to the layout and code in in the MainActivity class but when I try to code the buttons of another layout in the same Activity the app forces stop . Whats wrong ?
Ok I found out that is because of the context.
When you try to change other activity you have to use layoutinflater. Example below
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, null);
To work with widgets inside it like buttons or anything .
Button b = mylayout.findViewById(R.id.button);
b.setText("Successfully changed");
Now you can use myLayout as your changed layout.
Please sent me your Activities
What the text of problem ?
You may write next code to go to another activity
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),nameActivity.class));
}
});
Where button is name of your button
See that you xml-file doesnt have any mistakes
You are getting a crash because you are trying to access the layout when it is not inflated. In other words, you must call setContentView() on an Activity, or inflater.inflate() on a Fragment to instantiate the view and make the elements accessible for manipulation. So if you want to add buttons to another Activity, you would need to call its onCreate() and setContentView() before you can add buttons to it.
EDIT: In response to comments...
In order to access/manipulate/modify elements in a layout at runtime, they must first be instantiated, which happens when the view is inflated. So to add a button to an Activity at runtime, you would do it in the onCreate() method after calling setContentView() like this:
Keep in mind this is the onCreate() of your SECOND activity...not your main Activity. So your main activity would start this Activity, then the button would get created during the setup of the second Activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_second_activity;
Button button = new Button(this);
button.setText("Your New Button");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("NEW BUTTON", "I just clicked my new button!");
}
});
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_in_your_second_activity);
relativeLayout.addView(button);
}
If you are using a Fragment to display your UI, you can't access your UI elements until you have inflated your layout, which happens in the onCreateView() method. So you would do something like this in your Fragment code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
RelativeLayout relativeLayout = (RelativeLayout) view.findViewById(R.id.container_layout_that_holds_button);
//You would get your context from an onAttach() Override
Button button = new Button(context);
button.setText("Your New Button");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("NEW BUTTON", "I just clicked my new button!");
}
});
relativeLayout.addView(button);
return view;
}
You're likely getting a NullPointerException when you try to manipulate your layouts before they are created. Keep in mind that even if you have an XML file with layouts specified within, the actual objects for those elements won't be created until the system decides it needs them, which happens when you actually try to display the view.

Accessing a UI component (Button) inside several other UI components (ExpandableListView - GridView) in Android

In a xml, I am having LinearLayout.
Inside that I am using an ExpandableListView.
Every expand item contain just one view which is a GridView.
A GridView cell compose with three UI components which are ImageView, TextView and a Button.
How I have got control about those three UI components is as follow,
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) imageAdapterContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.single_grid_item, null);
viewHolder = new ViewHolder();
viewHolder.singleImageView = (ImageView) convertView.findViewById(R.id.singleGridItem_imageView);
viewHolder.singleTextView = (TextView) convertView.findViewById(R.id.singleGridItem_textView);
viewHolder.singleDownloadButton = (Button) convertView.findViewById(R.id.singleGridItem_download_button);
}
}
// ViewHolder is a static nested inner class
Things are working prety fine. That means each cell identify as different cells.
They have different images, and appropriate TextView labels and also Button click event also working fine.
For the button click I have used a downloading with a ProgressDialog. That also working fine.
What I want is disable the Button when the downloading in progress.
Downloading happening in a seperate AsyncTask class.
Please tell me how can I disable the button which user has clicked for downloading.
set the click able property of the button to false in the on click method and enable it on post execute -- (view v)
then set the property of v
Most of the time I have to wrte the answer for my own question.
This one also the same.
I have figure out the way.
I have override the button click event in the getView() method as follow.
viewHolder.singleDownloadButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Some code goes here...
new DownloadZipAsyncTask(imageAdapterContext, view).execute(zipFileUrl);
}
});
By the time I click the Download button, I am passing the button view to the DownloadZipAsyncTask class.
In that class, I am again creating Button instance and set the view invisible as follow in onProgressUpdate()
Button mybutton = (Button) view.findViewById(R.id.singleGridItem_download_button);
mybutton.setVisibility(View.INVISIBLE);
For button, it is working. But I can't change the ImageView or the TextView like that.
Because in the click event, we only pass the Button view only.
Therefore I am again in a problem with how to update a progress bar like that.
Again, ProgressDialog is not a problem, only the ProgressBar UI component give the problem.

Android: How to get a view given an activity inside a normal class?

I have a normal class (not an activity). Inside that class, I have a reference to an activity.
Now I want to access a view (to add a child) contained in the layout xml of that activity.
I don't know the name of the layout file of that activity. I only know the ID of the view, which I want to access (for example: R.id.my_view).
How can I do that?
Regarding the NullPointerException (which you should add to the question), always make sure you've called setContentView() in your Activity before trying to access a View defined in XML. Example usage:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
...
}
Then, somewhere,
ViewGroup group = (ViewGroup) context.findViewById(R.id.group); // In your example, R.id.my_view
The reason you need to have called setContentView() is that before it's called, your View(Group) doesn't exist. Because findViewById() is unable to find something that doesn't exist, it returns null.
As simple as that!
View view = activity.findViewById(R.id.my_view);
In case of the Layout:
LinearLayout layout = (LinearLayout) activity.findViewById(R.id.my_layoutId);
And to add the Views:
layout.addView(view);
You could make your method accept an Activity parameter and then use it to find the view by id.
Ex:
public class MyClass{
public void doSomething(Activity context){
TextView text=(TextView)context.findViewById(R.id.my_textview);
}
}
Then in your activity:
obj.doSomething(YourActivity.this);

findViewById in specific layout?

Instead of prefixing id's in xml, is it possible to specify the particular layout in code? For example, if I have 3 layouts, each with a button that has an id of "btn". Is it possible to specify which layout to findViewById(R.id.btn) in?
The basic context is defined via setContentView(R.lyaout.my_layout). If you inflate another layout using LayoutInflater.inflate() you get a layout object, lets call it buttonLayout. You can now differ between this.findViewById(R.id.button) and buttonLayout.findViewById(R.id.button) and both will give you different button references.
findViewById is a method of the View class. You can specify where the view should be searched for like that
final View container = new View(context);
container.findViewById(R.id.btn);
If your content view is a complex hierarchy that has several views with id btn, you will need to navigate to a subtree of the hierarchy and search from there. Suppose you have three LinearLayout views, each with a btn view somewhere in it. If you can first select the correct LinearLayout (by id, tag, position, or some other means), you can then find the correct btn view. If the relevant LinearLayout has id of branch1, for instance:
View parent = findViewById(R.id.branch1); // Activity method
View btn = parent.findViewById(R.id.btn); // View method
if you have your btns inside different Viewgroups, it is possible, but requires to give ViewGroups a different name! Easyiest will be for that purpose to define the Layout of the Button inside its own XML (i.e button_layout.xml)
inside your Activity you can do this:
public MyActivity extends Activity{
Button btn1, btn2, btn3;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
LinearLayout ll = new LinearLayout(this);
setContentView(ll);
btn1 = (Button)inflater.inflate(R.layout.button_layout, ll);
btn2 = (Button)inflater.inflate(R.layout.button_layout, ll);
btn3 = (Button)inflater.inflate(R.layout.button_layout, ll);
}
}

Categories

Resources