My Question: Is there a work-around for using an onTouchEvent in a FragmentActivity?
My Situation: I'm writing a simple flashlight app and I have a FragmentActivity where a user can swipe between colors (the whole screen is just one color. This app is for personal improvement). I want to be able to do a onLongPress event for options, a onDoubleTap event for hiding the navigation bar, and most importantly a touch event to control brightness of the app (I want to let the user scroll up and down for brightness changes, any ideas here are welcome! is the onFling event good for this?)
What I've tried: I have a GestureDetector with my implementation of an SimpleOnGestureListener. I override the onTouchEvent in the FragmentActivity, but I have just found out that this method is never called in a FragmentActivity (I also tested this with a Log.print in the method and it's never called). Is there a work-around? Thanks!
Salient Code:
MainActivity:
public class MainActivity extends FragmentActivity {
private GestureDetector gestureDetector;
private FragmentPagerAdapter mAdapter;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gestureDetector = new GestureDetector(getApplicationContext(), new MyGestureListener(getWindow()));
mAdapter = new ColorFragmentAdapter(getSupportFragmentManager(), getDefaultColorList());
ViewPager pager = (ViewPager) super.findViewById(R.id.viewpager);
pager.setAdapter(mAdapter);
pager.setCurrentItem(Math.round(mAdapter.getCount() / 2)); //Set current fragment to middle fragment
}
#Override
public boolean onTouchEvent(MotionEvent event) {
print("Sending touch event to gestureDetector.");
//This line is never run.
return gestureDetector.onTouchEvent(event);
}
/**
* Prints the given object to the log with the debug priority with the tag FLASHLIGHT
*
* #param object
*/
public static void print(Object object) {
Log.println(Log.DEBUG, "FLASHLIGHT", object.toString());
}
}
MyGestureListener :
public class MyGestureListener extends SimpleOnGestureListener {
private final Window window;
public MyGestureListener(Window window) {
super();
this.window = window;
}
#Override
public void onLongPress(MotionEvent e) {
//onLongPress code
}
#Override
public boolean onDoubleTap(MotionEvent e) {
//onDoubleTap code
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//onFling cod
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<android.support.v4.view.ViewPager
android:id="#+android:id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
I don't think you'd need anything else to answer the question, but let me know if you do.
So the solution to this is relatively easy. The problem is that the ViewPager is eating the touch event. So what I did was write my own implementation of a ViewPager and overrided the onTouchEvent(MotionEvent event) method by calling super.onTouchEvent(event) and then passing the event to the gestureDetector within the class.
Relevant Code:
MainActivity
public class MainActivity extends FragmentActivity {
private FragmentPagerAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
mAdapter = new FragmentAdapter(getSupportFragmentManager());
MyViewPager pager = (MyViewPager) findViewById(R.id.viewpager);
pager.setGestureDetector(new GestureDetector(this, new MyGestureListener(this)));
pager.setAdapter(mAdapter);
pager.setCurrentItem(Math.round(mAdapter.getCount() / 2));
}
}
MyViewPager
public class MyViewPager extends ViewPager {
private GestureDetector gestureDetector;
public MyViewPager(Context context) {
super(context);
}
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent e) {
return super.onTouchEvent(e) && gestureDetector.onTouchEvent(e);
}
}
MyGestureListener
public class MyGestureListener extends SimpleOnGestureListener {
private final Activity activity;
public MyGestureListener(Activity activity) {
super();
this.activity = activity;
}
#Override
public boolean onDoubleTap(MotionEvent e) {
//...
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
//...
}
//... etc...
}
layout_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<com.kentcdodds.flashlight.MyViewPager
android:id="#+android:id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
try doing this:
gestureDetector = new GestureDetector(this);
and on the TouchEvent this:
#Override
public boolean onTouchEvent(MotionEvent me) {
return gestureDetector.onTouchEvent(me);
}
Source
If you just want to simply detect when a user touches on the fragmentActivity use the following method:
public void onUserInteraction(){
Log.d("FragmentActivity","touched");
}
More info at : http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html
Related
I have a messaging app similar to whatsapp where there are messages videos and images in the chat activity. Now I want to implement a double tap like feature on this but the problem is I also have a onclicklistner attached to my image and video frame that opens up a fullscreenactivity showing the image in fullscreen or playing the video in fullscreen. So on double tap instead of liking the picture or video it simply opens the video or image in the fullscreen mode. Since in messages I don't have a onclick listner attached double tap like works fine. Any ideas on how I can make the double tap like work in case of the videos or images. I am fairly new to android development using Java. So any help is appreciated.
HI, I think the approach to take depends on the future of your app, using LongClick is kinda good but what if you want to achieve a zoom like onLongClick?
What I did below is that I created a subclass that extends GestureDetector.SimpleOnGestureListener and then in my GestureTest class, I an ontouchListener and return the gesture instance created before, finally I parse the listener to the button that has to perform the clicks, it can be any View object.
Finally, I used the TextView I created to display/monitor my actions.
GestureDetector like below:
public class GestureTest extends AppCompatActivity{
private Button btn;
private TextView actions;
private GestureDetector mDetector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gesture_test);
btn = findViewById(R.id.btn);
actions = findViewById(R.id.action);
mDetector = new GestureDetector(this, new SampleGestureListener());
View.OnTouchListener touchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return mDetector.onTouchEvent(event);
}
};
btn.setOnTouchListener(touchListener);
}
public class SampleGestureListener extends GestureDetector.SimpleOnGestureListener{
#Override
public boolean onDown(MotionEvent event) {
Log.e("EVENT","BUTTON PRESSED DOWN, NOT YET RELEASED WILL TRIGGER ONLONG-PRESS");
// don't return false here or else none of the other
// gestures will work
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.e("EVENT", "SINGLE CLICK EVENT");
actions.setText("THIS CLICK IS FOR IMAGE OR VIDEO TO OPEN ?");
return true;
}
#Override
public void onLongPress(MotionEvent e) {
Log.e("EVENT", "LONG PRESSED");
actions.setText("THIS IS ZOOM LIKE NOT DOUBLE CLICK!!!");
}
#Override
public boolean onDoubleTap(MotionEvent e) {
Log.e("EVENT", "DOUBLE CLICKED HAPPENED");
actions.setText("THIS CLICK IS TO LIKE IMAGE OR VIDEO ?");
return true;
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.e("EVENT", "SCROLLING");
actions.setText("YOU\" Scrolling on many images...");
return true;
}
#Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
Log.e("EVENT", "FLINGED");
actions.setText("THIS IS TINDER FLING LIKE ?");
return true;
}
}
}
AND BELOW IS MY activity_gesture_test.xml FOR TESTING:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btn"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="100dp"/>
<TextView
android:id="#+id/action"
android:textSize="20dp"
android:textColor="#color/black"
app:layout_constraintTop_toBottomOf="#+id/btn"
android:layout_width="match_parent"
android:layout_height="100dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
GoodLuck Coding.
try this for double click:
int i = 0;
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
i++;
Handler handler = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
i = 0;
}
};
if (i == 1) {
//Single click
handler.postDelayed(r, 250);
} else if (i == 2) {
//Double click
i = 0;
ShowDailog();
}
}
});
and for click listener:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
It is generally accepted to use long tap instead of double click in android apps. Try this:
yourView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
//do Your stuff here
return true;
}
});
For some reason, when I click on the Toolbar(toolbar) and Float button(button) in my app, the OnClickListener () method crashes the snippet and app
Although the ImageButton(OnOff) handler runs and does not crash the fragment
Fragment
public class ZnonkiFragment extends Fragment {
private SharedPreferences settings;
private ImageButton OnOff;
private ViewPager viewPager;
private DrawerLayout drawerLayout;
private MainActivity.PagerAdapter pagerAdapter;
private FloatingActionButton button;
final Context context = getActivity();
private androidx.appcompat.widget.Toolbar toolbar;
private TabLayout tabLayout;
private String ZvonOne, ZvonTwo;
private List<Fragment> list = new ArrayList<>();
private String url;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_znonki, container,
toolbar = view.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.menu));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context,"lel",Toast.LENGTH_LONG).show();
}
});
//...
addListenerOnButton(view);
return view;
}
public boolean checkString(String string) {
try {
Integer.parseInt(string);
} catch (Exception e) {
return false;
}
return true;
}
public void addListenerOnButton (final View viewOne){
OnOff = viewOne.findViewById(R.id.onOff);
button = viewOne.findViewById(R.id.floatingActionButton);
OnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//...
});
button.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(final View view) {
//...
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//...
});
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ZnonkiFragment">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:title="Звонки"
app:titleTextColor="#FFFFFF" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:clickable="true"
android:focusable="true"
app:backgroundTint="#color/colorAccent"
app:backgroundTintMode="src_atop"
app:srcCompat="#drawable/kek" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:isScrollContainer="true"
app:tabIndicatorColor="#android:color/white"
app:tabIndicatorHeight="6dp"
app:tabMode="scrollable"
app:tabSelectedTextColor="#android:color/white"
app:tabTextColor="#E6E6FA">
</com.google.android.material.tabs.TabLayout>
<ImageButton
android:layout_margin="16dp"
android:id="#+id/onOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#null"
app:srcCompat="#drawable/on" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/rager"
android:layout_width="match_parent"
android:layout_height="557dp"
android:layout_marginTop="105dp"
/>
</FrameLayout>
Although this code worked in the main activiti
I don't know why but there are no errors in debug mode
What Kundan has suggested is correct but the fix is much easier.
You don't need this:
final Context context = getActivity();
If you need to gain access to the context in a Fragment you can call requireContext() if you need access to the Activity you can call requireActivity()
So your toast message can become:
Toast.makeText(requireContext(),"lel",Toast.LENGTH_LONG).show();
I think main cause of this issue is
final Context context = getActivity();
which is used in
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context,"lel",Toast.LENGTH_LONG).show();
}
});
please note the getActivity() method returns the current activity with which this fragment is attached. and you are calling while the fragment object is creating before it is attached to activity.
you can change the above code to :
Context context;
and override the method as
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
Hope this answers your question.
The solution is simple
In your fragment class file, dont create custom function for calling click events rather you can use the android's defaul method by simply implementing them in your class file and then override it. Thats makes the code more simpler and reusable in future.
public class ZnonkiFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener {
private SharedPreferences settings;
private ImageButton OnOff;
private ViewPager viewPager;
private DrawerLayout drawerLayout;
private FloatingActionButton button;
final Context context = getActivity();
private TabLayout tabLayout;
private String ZvonOne, ZvonTwo;
private List<Fragment> list = new ArrayList<>();
private String url;
private Toolbar mToolbar;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_znonki, container, false);
mToolbar = view.findViewById(R.id.toolbar);
mToolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_launcher_background));
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "lel", Toast.LENGTH_LONG).show();
}
});
//...
OnOff = view.findViewById(R.id.onOff);
OnOff.setOnClickListener(this);
OnOff.setOnLongClickListener(this);
button = view.findViewById(R.id.floatingActionButton);
return view;
}
public boolean checkString(String string) {
try {
Integer.parseInt(string);
} catch (Exception e) {
return false;
}
return true;
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.onOff:
//call your onclick function here...
break;
case R.id.floatingActionButton:
//call your onclick function here...
break;
}
}
#Override
public boolean onLongClick(View view) {
switch (view.getId()) {
case R.id.floatingActionButton:
//call your long click function here...
break;
}
return false;
}
}
I have left comments on particular Loc where you can add your code and check it. And the toolbar was crashing due to improper importing of the libraries. If you havent used the androidx library into your gradle file then you can go with simple toolbar which is of "import android.support.v7.widget.Toolbar". This will surely stop your onclick crash on toolbar.
If there is any issue, just let me know. Thank you.
When making a custom component for Android, as far as I understood, I need:
one xml file with the layout for the component;
one java class.
Tried to make one, just for practice. Use two progressbars and one button in the XML, and create the class, than tried out in my main activity, worked fine.
But now I'm loking how to set OnClickListener on my button through the activity, and in this part I'm lost.
My loading_button.xml:
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:progress="0"
android:id="#+id/pg_top" />
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btn_ok"
android:background="#color/colorPrimary"
android:textColor="#ffffff"
android:layout_below="#+id/pg_top"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:progress="0"
android:id="#+id/pg_bottom"
android:layout_below="#+id/btn_ok"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</merge>
Here the LoadingButton.java:
public class LoadingButton extends RelativeLayout{
private ProgressBar pbTop;
private ProgressBar pbBottom;
private Button btnOk;
private int pbTopProgress = 0;
private int pbBottomProgress = 0;
public LoadingButton(Context context, AttributeSet attrs) {
super(context, attrs);
View view = View.inflate(context, R.layout.loading_button, this);
btnOk = (Button) view.findViewById(R.id.btn_ok);
pbTop = (ProgressBar) view.findViewById(R.id.pg_top);
pbBottom = (ProgressBar) view.findViewById(R.id.pg_bottom);
btnOk.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Doing stuff ok
}
});
}// LoadingButton
}
The setOnClickListener in the class works, but how can I set it from my main activity?
MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// My new component (it's id in activity_main.xml is 'lb')
LoadingButton lb = (LoadingButton) findViewById(R.id.lb);
// QUESTION - how to make something like this with btnOk:
lb.btnOkSetOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Do stuff
}
});
}
}
If this is possible, how?
If not, what is the right approach to make a custom component and set clickListeners on specific element of this component?
Best approach to handle all view click in LoadingButton (For custom view). And create interface.
public class LoadingButton extends RelativeLayout {
public interface OnLoadingButtonClickListener{
void onLoadingButtonClickListener();
}
private ProgressBar pbTop;
private ProgressBar pbBottom;
private Button btnOk;
private int pbTopProgress = 0;
private int pbBottomProgress = 0;
private OnLoadingButtonClickListener mONOnLoadingButtonClickListener;
public LoadingButton(Context context, AttributeSet attrs) {
super(context, attrs);
View view = View.inflate(context, R.layout.loading_button, this);
btnOk = (Button) view.findViewById(R.id.btn_ok);
pbTop = (ProgressBar) view.findViewById(R.id.pg_top);
pbBottom = (ProgressBar) view.findViewById(R.id.pg_bottom);
btnOk.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mONOnLoadingButtonClickListener != null){
mONOnLoadingButtonClickListener.onLoadingButtonClickListener();
}
}
});
}// LoadingButton
public void setOnLoadingClickListener(OnLoadingButtonClickListener onLoadingClickListener){
mONOnLoadingButtonClickListener = onLoadingClickListener;
}
}
And implement OnLoadingButtonClickListener in your activity.
public class MainActivity extends AppCompatActivity implements LoadingButton.OnLoadingButtonClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// My new component (it's id in activity_main.xml is 'lb')
LoadingButton lb = (LoadingButton) findViewById(R.id.lb);
lb.setOnLoadingClickListener(this);
}
#Override
public void onLoadingButtonClickListener() {
//do your stuff on ok button click
}
}
Override setOnClickListener(OnClickListener listener) in your custom Java class. Inside it, write:
btnOk.setOnClickListener(listener);
where listener is an argument of your custom view's setOnClickListener() function.
That will make your whole view clickable and click on your button will be performed. Of couse add android:clickable="true" to your custom view's root layout.
In the component
class Example #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
defStyleRes: Int = 0) : ConstraintLayout(context, attrs, defStyle) {
var clickListener: () -> Unit = { }
init { }
private fun initListeners() {
binding.button.onClick {
clickListener()
}
}
In the activity / fragment
component.clickListener = { }
And the best part, you can send data on the component and receive it in the landa
I wrote below method to show progress bar but the progress bar rounded by white box fits the screen width and i do not know why.
public void showProgressBar() {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
ProgressBar pbar = new ProgressBar(activity, null,
android.R.attr.progressBarStyleLargeInverse);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(30, 50);
pbar.setLayoutParams(params);
builder.setView(pbar);
builder.setCancelable(true);
progressBar = builder.create();
progressBar.show();
}
when execute the above method the progress shown as this image.
progress bar problem
How i can solve this issue?
You should use a ProgressDialog and no, it doesn't fit the screen width.
ProgressDialog pd=new ProgressDialog(activity);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
This should give you what you want.
Do this:
ProgressDialog pd;//declare as a global variable
public void showProgressBar() {
pd=new ProgressDialog(activity);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
}
Dismiss the ProgressDialog wherever you want later.
I solved it by stupid way but it works fine at me.
public abstract class AbstractScreen implements IActivity {
protected Response response;
protected FragmentActivity activity;
private CustomProgressDialog progress;
public AbstractScreen(FragmentActivity activity) {
this.activity = activity;
}
public abstract void loadScreen();
#Override
public void preExecution() {
// TODO Auto-generated method stub
}
#Override
public void postExecution(Response response) {
// TODO Auto-generated method stub
}
public void showProgressBar() {
progress = new CustomProgressDialog(activity);
progress.show();
}
public void closeProgress() {
progress.dismiss();
}
public FragmentActivity getActivity() {
return activity;
}
private class CustomProgressDialog extends Dialog {
private Context context;
public CustomProgressDialog(Context context) {
super(context);
this.context = context;
loadScreen();
}
public void loadScreen() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.progress);
setCancelable(false);
}
}
}
add this layout file also.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_marginRight="-7dp"
>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleLarge"
android:id="#+id/progressbar"
android:layout_gravity="center_horizontal"
android:max="100"
/>
</LinearLayout>
I have an abstract Activity as most of my activities share the same menu:
public abstract class ActivityBase extends Activity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menubar, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
//...
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//...
}
}
Now, when I use that class (inherit from it), the findViewById() method doesn't work anymore. Doesn't matter if I even inherit from it in that particular class, once it is somewhere in the inheritance tree, it doesn't work anymore. For example:
public class SomeOther extends ActivityBase {
}
public class Home extends Activity {
#Override
public void onCreate (Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
Button b = (Button)findViewById(R.id.button); // fails, NullPointerException
}
What could be the cause of this, and even more importantly, how can I fix it?
In my case this work perfect (try this)...
public abstract class ActivityBase extends Activity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
//..
return true;
}
}
and
public class MyActActivity extends ActivityBase {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.e("HI", "Hello");
TextView tv=(TextView)findViewById(R.id.Settings_phoneNumbersT1);
Log.e("HI", tv.toString());
}
}
and main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/Settings_phoneNumbersT1"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff" android:text="Hellofffff"/>
</LinearLayout>
So, I don't think it is problem of Abstract ActivityBase class.
try this...
Button b = (Button)Home.this.findViewById(R.id.button);
its to make sure that your present class's findviewById is called and not the super class's..
The NullPointerException was caused someplace else and just manifested with that method. If you derive from Application and try to call getSharedPreferences, it fails, but you can't pinpoint it.