this is MainActivity
//class declare
public class MainActivity extends Activity {
// a lot of code
}
//OnCreate Set
setContentView(R.layout.activity_main);
and Inside having a TableLayout with ID R.id.widget101, TableLayout having a dynamic created LinearLayout.
here is the second activity code,trying to get the MainActivity TableLayout and get all the inside LinearLayout child
//class declare
public class SecondActivity extends Activity {
// a lot of code
}
//OnCreate Set
setContentView(R.layout.second);
public void EnableButton(boolean bool){
View view = LayoutInflater.from(getApplication()).inflate(R.layout.activity_main, null);
ViewGroup layout = (ViewGroup) view.findViewById(R.id.widget101);
if (layout != null){
Log.d(null,"EnableButton getchild="+layout.getChildCount()+"");
Log.d(null,"EnableButton Function");
}
}
Problem Occurs here, When the Second Aciticity calling the MainActivity to get the TableLayout Child are return 0
===============================================================
this is how i call the SecondActivity
public class MainActivity extends Activity
implements OnClickListener {
//overrides the OnClickListener interface method
#Override
public void onClick(View arg0) {
if(arg0.getId() == R.id.btnWEmas){
//define a new Intent for the second Activity
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("From_LocationName",global.From_LocationName);
intent.putExtra("To_LocationName",global.To_LocationName);
TextView textview = (TextView) findViewById(R.id.lblPrice);
intent.putExtra("Price",textview.getText());
//start the second Activity
this.startActivity(intent);
}
// still have a lot of code
put this in your first activity
static ViewGroup layout ; //define it globally
layout = (ViewGroup) view.findViewById(R.id.widget101); //put it inside the oncreate of main activity
and use this object to second activity
public void EnableButton(boolean bool){
View view = LayoutInflater.from(getApplication()).inflate(R.layout.activity_main, null);
if (MainActivity.layout != null){
Log.d(null,"EnableButton getchild="+MainActivity.layout.getChildCount()+"");
Log.d(null,"EnableButton Function");
}
}
You should follow the following scenario :
create a Custom class file, which contains the Table layout and its children elements. Create a default Constructor with a context parameter. Please follow below link for more clearity.
https://stackoverflow.com/a/20367698/1944782
Here I have created a custom Toast, You can customize your Table Layout according that.
One more thing, please ignore the use of static variable as much as possible. It leads to memory leak and also crashes the app.
Related
I have a main Activity and several Fragments. On each fragment I have several TextView elements. I want to change font size of TextViews on the current displayed Fragment from Main Activity. Therefore I want to hold list of TextView elements on the currentFragment using a Listener.
But I don't know how to implement such Listener?
Is the listener right way to do that?
If there is a another way to achieve this, I wanted to know. Any answers welcome. Thanks.
If I got your question right, you could just access the current fragment's TextView object from the Main Activity and use the setTextSize() method.
You declare a list of TextViews and provide a method to add the textviews to the list.
And you also provide a method to signal the activation state. This method will go through the list of textviews calling the changes you need one by one.
From your main activity you will call fragment.changeListeningTextViews();
This goes in the Fragment:
private ArrayList<TextView> listeningTextViews;
public void addListeningTextview(TextVew tv){
//Here check if the text view is already added not to add it twice.
listeningTextViews.add(tv);
}
public void changeListeningTextViews(){
for(TextView tv : listeningTextViews){
tv.setFont(...);
//What you want called on each TextVeiw
}
}
In onCreateView you add the text views to the list:
TextView textView1 = (TextView) rootView.findViewById(R.id.aview);
addListeningTestview(textView1);
TextView textView2 = (TextView) rootView.findViewById(R.id.anotherview);
addListeningTestview(textView2);
...
Note: If it were the other way round when you need the Main Activity to listen on events coming from the fragment the solution would be different and the it would involve a custom Listener interface to be implemented by the Main Activity.
I had implemented as below. It works well fine but I don't know how clear solution it is.
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
//
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action buttons
switch(item.getItemId()) {
case R.id.smallFontSize:
FontSizeHelper.updateFontSize(Constants.fontSize1);
return true;
case R.id.mediumFontSize:
FontSizeHelper.updateFontSize(Constants.fontSize2);
return true;
case R.id.largeFontSize:
FontSizeHelper.updateFontSize(Constants.fontSize3);
return true;
case R.id.extraLargeFontSize:
FontSizeHelper.updateFontSize(Constants.fontSize4);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
public class FontSizeHelper {
public static List<View> viewElements = new ArrayList<>();
public static void initFontElements(){
viewElements = new ArrayList<>();
}
public static void addFontEelements(View view){
viewElements.add(view);
}
public static void updateFontSize(int fontSize){
for(View v : viewElements){
if(v instanceof TextView){
((TextView) v).setTextSize(fontSize);
}
}
}
}
public class FragmentA extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.a_fragment, container, false);
//initialize empty list for View objects.
FontSizeHelper.initFontElements();
//add View object/TextViews into list
FontSizeHelper.addViewEelements(textView1);
FontSizeHelper.addViewEelements(textView2);
FontSizeHelper.addViewEelements(textView3);
//..etc
}}
public class Home extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.home,null);
}}
This is the whole code for fragment tab 1..
I have a program with two TabFragments , and I want to declare an image button and button intent in fragment tab 1 and 2, but I can't do it , and the findviewbyid did not work..
What can I do to declare buttons intent ??
To handle button clicks (and view clicks in general) View.OnClickListener interface is used. All you have to do is override its onClick method and assign it to a view by calling setOnClickListener().
You can also find a thorough tutorial here.
UPD: Your method should look like this:
public View onCreateView(.....) {
// assign inflated view to a variable
View v = inflater.inflate(R.layout_services, null);
// set your listener
v.findViewById(R.id.imageButton).setOnClickListener(.....);
// return the view in the end
return v;
}
The problem is that you're instantly returning the inflated view and the code below wouldn't run at all, this is why there's that error.
UPD2: Now the problem is that startActivity method is receiving Context as a first parameter, so you should pass your activity there by calling getActivity() (instead of passing Services.this). You can read more here.
UPD3: You don't seem to understand what your code does. Your findViewById call is useless because it's not getting assigned to a variable, and your setOnClickListener is getting applied to the entire fragment view. Here's what that part should look like:
ImageButton button = (ImageButton) v.findViewById(R.id.imageButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Activity activity = getActivity();
Intent intent = new Intent(activity, Admin.class);
activity.startActivity(intent);
}
});
I'd recommend to learn how all those methods work (at least have a look at the reference, to begin with: here and here) before trying to actually write an application. Good luck with it.
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);
I am writing an android application where the user can add and remove fields interactively. Each field the user add has some buttons, and value which the user should be able to interact with. I thought to create a subclass to handle the field I can add which will hold it's own onClickListener but I'm not sure how to do so.
Here is some pseudo code which should make my intention clear.
Say I have a class , vClass:
public class sClass extends View implements onClickListener{
this.setContextView(R.layout.vClass);//how do I do this in a correct way?
#Override
public void onClick(View v){ //add code here
}
}
and aClass which is the main class of the application.
public class aClass extends Activity implements onClickListener{
Button b;
LayoutInflater i;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.b =(Button)this.findViewById(R.id.btn);
b.setOnClickLister(this);
}
#Override
public void onClick(View v){
//this is what I have now to add View
final LinearLayout canvas =(LinearLayout)aClass.this.findViewById(R.id.main);
View cv =this.inflater.inflate(R.layout.counter, canvas, false);
canvas.addView(cv);
}
}
how can I use the vClass to add elements to the aClass.
Typing this is I thought about another solution.
If I keep track of the id's of all the views I have added (without the subcomponents) can I do something of that kind:
View vv = findViewById(id);
Button bb = vv.findViewByIf(R.id.xmlId);
where id is an id I have assigned to the view which I know and xmlId is a string I have specified in the xml file?
Thanks
Yotam
For solution, read the discussion below
IDs used in layouts are not necessarily unique, so i guess you should keep the added Views in an ArrayList, as
View cv =this.inflater.inflate(R.layout.counter, canvas, false);
this.viewList.add(cv);
canvas.addView(cv);
or you could declare an index member inside your sClass implementation, and store the added indices in an ArrayList:
private int index;
public sClass(final int index)
{
this.index = index;
}
public int getIndex()
{
return this.index;
}
#override
public boolean equals(Object obj)
{
return ((obj instanceof sClass) && (((sClass)obj).getIndex() == this.index));
}
Both ways you have access to the view you want.
The button that lays inside the view is accessible via the findViewById() method
Button bb = vv.findViewById(R.id.buttonId);
where R.id.buttonId was declared in the vv view's layout xml file, as follows:
<Button android:id="#+id/buttonId" [...] />
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle(R.string.app_name);
setContentView(new SampleView(this));
}
}
SampleView.java:
public class SampleView extends View {
#Override
protected void onDraw(Canvas canvas) {
if (certaincondition = true) {
//add elements to canvas etc
} else {
//How do I do the below? The layout is defined in xml.
//I do not want to use Intent. Please help me
//create a layout from resource R.layout.idAbout and transfer control.
}
}
}
Use a layout inflater:
View newRootViewElement;
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
newRootViewElement= li.inflate(R.layout.idAbout, null);
You can inflate a layout using
View.inflate(getContext(), R.layout.idAbout, viewParent);
where viewParent is a ViewParent that will be the parent of the inflated view (and can be null).
But what are you trying to do? It's more than a little odd to start a new activity or to modify the view hierarchy from within onDraw(). You might want to post a runnable to a Handler that will do what you want on the next cycle of the event loop. To start a new activity (such as displaying “About” info for the app) you should take a look at the Intent class.