Usually you would start an activity with something like the following:
private void llMenuSettings_Click() {
this.runOnUiThread(new Runnable() {
public void run() {
Intent intent = new Intent(XXXXXXXX.this, View_Settings.class);
startActivity(intent);
XXXXXXXX.this.finish();
}
});
}
However I am extending a LinearLayout:
public class MenuContainer extends LinearLayout {
}
Therefore I have run into a couple of issues:
How would you know what XXXXXXXX is in the example as the LinearLayout can be included in multiple Layouts?
startActivity() does not exist in a LinearLayout class?
There are a few similar questions but none that fully answer the above scenario therefore hoping this can be answered and help others in the future?
Inside your LinearLayout extending class, you could create the following method:
public void launch() {
Intent i = new Intent(getContext(), YourActivity.class);
getContext().startActivity(i);
}
Use the getContext() method inside your customview to retrieve the Context and start a new Activity.
Related
I want to create a method that, when implemented in other classes, you just need to pass some parameters and then call the - onclick() function to set the element.
At the moment, I´ve just done this. But this gives me a RunTimeException
Unable to start activity ComponentInfo{com.example.test/com.example.testActivity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
my code:
Class: clickeable
imports ...
public class ClickeableOptions implements View.OnClickListener{
private CardView cardView;
private Context cont;
private Class actTarget;
public OpcionesMainClickeables() {}
public ClickeableOptions(CardView cardView, Context cont, Class actTarget) {
this.cardView = cardView;
this.cont = cont;
this.actTarget= actTarget;
}
//Getters and Setters
#Override
public void onClick(View v) {
getCardView().setOnClickListener(this);
Intent intent = new Intent(this.getCont(), this.getActTarget());
startActivity(intent);
}
}
And i want to implement this class like this...
public class MainActivity extends AppCompatActivity{
private CardView cvRegistration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cvRegistration = (CardView) findViewById(R.id.cvRegistration);
ClickeableOptions optionRegistration = new ClickeableOptions(
cvRegistration, this, Registration.class
);
optionRegistration.onClick(optionRegistration.getCardView());
}
I've implemented the method in the same file, but I want to do it this way to keep things more tidy.
I think the problem is in the use of this, but i really don't get it
No need to call onClick explicitly from your Activity. Just try like below:
public ClickeableOptions(CardView cardView, Context cont, Class actTarget) {
this.cardView = cardView;
this.cont = cont;
this.actTarget= actTarget;
this.cardView.setOnClickListener(this);
}
And inside onClick
#Override
public void onClick(View v) {
Intent intent = new Intent(getCont(), getActTarget());
getCont().startActivity(intent);
}
And remove this line from Activity.
//optionRegistration.onClick(optionRegistration.getCardView());
Now when you clicked your CardView, Then Activity transitions start.
Try to replace this line:
startActivity(intent);
with
getCont().startActivity(intent);
Also, why are you inheriting ClickeableOptions from AppCompatActivity?
Although you have instantiated the ClickeableOptions (derived from Activity) object, none of its Activity life cycle methods have been called and none of the super class instantiation related work (normally should be done in onCreate) has been accomplished. Hence the ActivityThread is simply null and you've got an exception when invoking
startActivity(intent);
If you want to start another Activity on your CardView click then you need to
follow Leo Leontev's advice:
call
getCont().startActivity(intent)
instead of
startActivity(intent)
move the line
getCardView().setOnClickListener(this)
to the ClickeableOptions custom constructor's most bottom line
delete this line from your MainActivity$onCreate() method:
optionRegistration.onClick(optionRegistration.getCardView());
After all of above is done you'll be able to start new activity on click event.
I need to define a layout for multiple activities in android and from the UI part, it is successful. But to code those elements to perform on each click listeners, I need to define it in all the java pages I use.
Can we globally define this in a java page and include it in the required pages?
menuButton = findViewById(R.id.menuButton);
menuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(), MenuActivity.class);
startActivity(i);
finish();
overridePendingTransition(0, 0);
}
});
Yes and No.
You can create a BaseActivity which has the common logic that has to be executed for each button click.
But you need to implement the listener for the button on specific activity, since life cycle of each activity is independent of other activity.
To make the code readable better (avoiding implementing listener/setOnclickListener), you can use ButterKinfe, and create a method for OnClick() annotation, and call the method in BaseActivity.
What you essentially want to do is call the findViewById(), which can only be called if you have a reference to a Context variable. You should use your Activity Context, hence you pass this to the static function, which can then access all methods accessible via Context .
public class ExampleActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MenuUtils.setListener(this);
}
}
Define the static class like this:
public static class MenuUtils{
public static void setListener(Context context){
menuButton = context.findViewById(R.id.menuButton);
menuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do stuff
}
});
}
}
What you should be careful about is that any Activity you pass to this function should have a menuButton in it's layout, otherwise you run the risk of getting a NullPointerException, which is when findViewById() cannot find menuButton.
Please i will like to have a method/function in a separate class
that will enable me to go to next activity or fragment class when i call it
here is my little try of code
inside my go_to.class i have this below
for activity
void goToActivity(Activity t){
startActivity(new Intent(this, t.class));
}
void goToFragment(Fragment f,package.com.R l){
getSupportFragmentManager().beginTransaction().add(l,new f).commit();
}
and to use example
goToActivity(mynextactivity.class);
goToFragment(mynextfragment.class,R.id.fragment_layout);
Any help is welcome
From non activity class you can create a function it like this:
public static void goToHomeActivity(Context context)
{
Intent i = new Intent(context, ActivityDashboard.class);
context.startActivity(i);
}
Then call it like this MyUtils.goToHomeActivity(context);
Alternatively, from activity class like this:
private void goToHomeActivity()
{
Intent i = new Intent(getBaseContext(), ActivityDashboard.class);
context.startActivity(i);
}`
Then call it like this goToHomeActivity();
I later solve it this way after many trial:
What i am trying to achive is to have a function to call new activity class and fragment when a button is clicked on at runtime
void goToActivity(Class t){
startActivity(new Intent(this, t));
}
my where i have been getting the fragment concept wrong is fragment is not indepent activity class, so to overcome fragment need anactivity parent or root layout to hold the fragment layout that is you can never start fragment instance alone like activity which is very big issure for begginers to understand
void goToFragment(Fragment f){
fragmentTransaction.replace(R.id.your_layout, f);
fragmentTransaction.addToBackStack(null);
}
or if you cannot determine your xml layout you can write it like this:
void goToFragment(int l,Fragment f){
fragmentTransaction.replace(l, f);
fragmentTransaction.addToBackStack(null);
}
Thank you all for your help
I'm trying to define a custom Java class (extending a LinearLayout), which needs to start an activity on click. My code looks like this :
public ArizaSatiri(Context context/*, AttributeSet attrs , final Activity aktivite*/ , JSONObject mysql_satiri)
{
super(context/*, attrs*/);
// code to initialize my view :
final Context finalContext = context;
this.setOnClickListener(new OnClickListener() {#Override
public void onClick(View v) {
Intent newIntent = new Intent(finalContext, ArizaDetaylari.class);
finalContext.startActivity(newIntent);
}//onClick
});
}
But when I clicked on the instantiated view, I get the error :
Calling startActivity() from outside of an Activity context requires the
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
As you can see from the code, I tried passing the Activity to the constructor, and that worked. But is that the correct way? Which way would you reccomend ?
Edit:
And I also need to call setTypeFace() at some point. Should I use context, or Activity for that ?
Try this:
this.setOnClickListener(new OnClickListener() {#Override
public void onClick(View v) {
Intent newIntent = new Intent(finalContext, ArizaDetaylari.class);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
finalContext.startActivity(newIntent);
}//onClick
});
You can put your code into onAttachedToWindow() of your custom view class.
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final Context context = ArizaSatiri.this.getContext();
Intent intent = new Intent(context , ArizaDetaylari.class);
context.startActivity(intent);
}
});
}
This helps because this function is called after your view is added to the activity, the view has the reference of it. Constructor of views probably run before being added to the activity, thus the error.
This should also work if you declare your view in xml instead of creating it programmatically. (Not tested yet)
If take a look to the Context class reference you could see that Activity is an indirect subclass. So if you use an Activity as Context your code should work.
For example:
public ArizaSatiri(Context context, JSONObject mysql_satiri){ ...}
you can change the call to the ArizaSatiri constructor:
new ArizaSatiri(myActivity, mysql_satiri);
Hope it helps.
If context (finalContext) that you are using is referring to ApplicationContext then you need to use the flag. Just add the sentence newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); before finalContext.startActivity(newIntent);
Problem with this approach especially when you are starting something outside of your app for ex: mail client etc, is it will continue to be there in the recent apps stack even after the activity is completed, in case of mail client it continues to be there even after mail has been sent
I am very new with android development. My app has a lot of views/Activity and user can jump from one view to another depending his/hers inputs. so i thought of creating an interface IView which will have a function
void openNewView(Class viewClass);
and the function in the view class would look something like this
public void openNewView(Class viewClass)
{
Intent intent = new Intent(this, viewClass.class);
startActivity(intent);
}
The whole idea is that my controller can listen for user inputs and then call openNewView as per the requirement.
The issue that i am facing is with java not accepting a parameter of type Class
What is it that i am doing wrong here. is there a work around what i am trying to achieve.
One good approach would be extend all your activities from an abstract Activity like this:
public abstract class BaseActivity {
//....
public void openNewView(Class viewClass) {
Intent intent = new Intent(this, viewClass.class);
startActivity(intent);
}
}
Doing this way you don't have to copy your code in every activities and keep code clean.
try by adding current Context param in openNewView method as:
void openNewView(Class viewClass,context);
and in your function :
public void openNewView(Class viewClass,Context context)
{
Intent intent = new Intent(context, viewClass.class);
context.startActivity(intent);
}