I need to detect when a VideoView is paused, so I can hide some UI elements on my screen. VideoView does not have a mechanism to inform you of a pause event. How do I do this?
I haven't seen a good answer to this (so many people using threads). Here's mine:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;
public class PlayStateBroadcastingVideoView extends VideoView{
public interface PlayPauseListener {
void onPlay();
void onPause();
}
private PlayPauseListener mListener;
public PlayStateBroadcastingVideoView(Context context) {
super(context);
}
public PlayStateBroadcastingVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PlayStateBroadcastingVideoView(Context context, AttributeSet attrs, int theme) {
super(context, attrs, theme);
}
#Override
public void pause() {
super.pause();
if(mListener != null) {
mListener.onPause();
}
}
#Override
public void start() {
super.start();
if(mListener != null) {
mListener.onPlay();
}
}
public void setPlayPauseListener(PlayPauseListener listener) {
mListener = listener;
}
}
It works because upon diving into the code (at least as of 5.0), the only function that puts it into the pause state is pause, and the only one that puts it into the playing state is start. So we simply hook these to notify us via a listener. Then use this class in your layout in place of VideoView.
Related
i would like to create a class, which extends Button and implement a method, which is alwasy called, when the Button is clicked. But i still want it's OnClickListener to be called.
My Idea is to save the OnClickListener into a private member when the constructor or setOnClickListener is called and then set the OnClickListener to my own OnClickListener. This one would then call my method and the saved OnClickListener.
But i don't see how i can get the OnClickListenr, i only see, how to set it.
Is there a way to acces it?
Or do you have a better idea? (it doesn't matter wheter my method is called before or after the OnClickListener)
I guess you could do this:
public class OnceClickedTwiceRunButton extends Button{
public OnceClickedTwiceRunButton(Context context) {
super(context);
}
public OnceClickedTwiceRunButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public OnceClickedTwiceRunButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private OnClickListener extraClickMethod;
#Override
public void setOnClickListener(OnClickListener newListener)
{
super.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
DefaultClickMethod(v);
if(extraClickMethod != null)
{
extraClickMethod.onClick(v);
}
}
});
extraClickMethod = newListener;
}
private void DefaultClickMethod(View v)
{
//TODO
}
}
i am new to android .
i was working with android canvas and i wonder how does SurfaceView class functions work when their function defination is empty in the android source code .Here is the android surface view class source code
package android.view;
import com.android.layoutlib.bridge.MockView;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
public class SurfaceView extends MockView {
public SurfaceView(Context context) {
this(context, null);
}
public SurfaceView(Context context, AttributeSet attrs) {
this(context, attrs , 0);
}
public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SurfaceHolder getHolder() {
return mSurfaceHolder;
}
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
#Override
public boolean isCreating() {
return false;
}
#Override
public void addCallback(Callback callback) {
}
#Override
public void removeCallback(Callback callback) {
}
#Override
public void setFixedSize(int width, int height) {
}
#Override
public void setSizeFromLayout() {
}
#Override
public void setFormat(int format) {
}
#Override
public void setType(int type) {
}
#Override
public void setKeepScreenOn(boolean screenOn) {
}
#Override
public Canvas lockCanvas() {
return null;
}
#Override
public Canvas lockCanvas(Rect dirty) {
return null;
}
#Override
public void unlockCanvasAndPost(Canvas canvas) {
}
#Override
public Surface getSurface() {
return null;
}
#Override
public Rect getSurfaceFrame() {
return null;
}
};
}
so how does this work when we write
canvas c = holder.lockCanvas(null);
or
holder.unlockCanvasAndPost(c);
when we have nothing in source code to process.. i mean where is the code to get the work done. if help me find it..
The full SurfaceView source code is in the AOSP code on Github:
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/SurfaceView.java
It appears that you're looking at the source for the stub library.
For the SDK, a library is generated that has entries for all public classes, fields, and methods, but no implementation. You build your app against that, rather than the actual library, so that your build fails if you try to use classes, fields, or methods that aren't part of the official Android API.
If you look in the actual source for SurfaceView you will see methods like setWindowType() (line 415) that have #hide in the javadoc. Even though the method is "public" in the Java-language sense, it's not part of the published API, and is therefore excluded from the stub library.
I have an array of EditText and I want to disable the standard keyboard Android that appears every time I click on them.
these are the parts code I am using:
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
for (i=0;i<dim*dim;i++){
imm.hideSoftInputFromWindow(value[i].getWindowToken(), 0);
value[i].setOnTouchListener(this);
value[i].setOnClickListener(this);
value[i].setOnFocusChangeListener(this);
}
EDIT:
I created a new class, with these lines of code:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
public class KeyboardControlEditText extends EditText {
private boolean mShowKeyboard = false;
public void setShowKeyboard(boolean value) {
mShowKeyboard = value;
}
// This constructor has to be overriden
public KeyboardControlEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Now tell the VM whether or not we are a text editor
#Override
public boolean onCheckIsTextEditor() {
return mShowKeyboard;
}
}
and in my main class in OnCreate:
for (i=0;i<dim*dim;i++){
((KeyboardControlEditText) value[i]).setShowKeyboard(false);
value[i].setOnTouchListener(this);
value[i].setOnClickListener(this);
}
You need to create your own EditText class for this. Then, override the default onCheckIsTextEditor and return false.
public class NoKeyboardEditText extends EditText {
// This constructor has to be overriden
public NoKeyboardEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Now tell the VM that we are not a text editor
#Override
public boolean onCheckIsTextEditor() {
return false;
}
}
Make sure you substitute in the correct name for the new EditText. For example, if your package is com.example.widget, you'd want to use <com.example.widget.NoKeyboardEditText ... />.
If you need this to be dynamic, you can get even fancier:
public class KeyboardControlEditText extends EditText {
private boolean mShowKeyboard = false;
public void setShowKeyboard(boolean value) {
mShowKeyboard = value;
}
// This constructor has to be overriden
public KeyboardControlEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Now tell the VM whether or not we are a text editor
#Override
public boolean onCheckIsTextEditor() {
return mShowKeyboard;
}
}
That way, you can call ((KeyboardControlEditText) myEditText).setShowKeyboard(false); to change it at runtime.
I cant seem to find an event that listens for playback state. I am mostly interested in the play/pause state. I am using MediaController which has a Play/Pause button, but I have a secondary button that also controls Play/Pause. Using my custom button, I can play/pause, but if I play/pause using the MediaController play/pause button, I currently have no way to change the image on my custom play/pause button to either play or pause.
Is there an event that I do not know about so I can do some work during play/pause?
This is a very similar question: How to catch event when click pause/play button on MediaController
If you're using the MediaController in combination with a VideoView, it should be relatively easy to extend the latter and add your own listener to it.
The custom VideoView would then look something like this in its most basic form:
public class CustomVideoView extends VideoView {
private PlayPauseListener mListener;
public CustomVideoView(Context context) {
super(context);
}
public CustomVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setPlayPauseListener(PlayPauseListener listener) {
mListener = listener;
}
#Override
public void pause() {
super.pause();
if (mListener != null) {
mListener.onPause();
}
}
#Override
public void start() {
super.start();
if (mListener != null) {
mListener.onPlay();
}
}
public static interface PlayPauseListener {
void onPlay();
void onPause();
}
}
Using it is identical to using a regular VideoView, with the only difference being that we can now hook up our own listener to it.
// Some other code above...
CustomVideoView cVideoView = (CustomVideoView) findViewById(R.id.custom_videoview);
cVideoView.setPlayPauseListener(new CustomVideoView.PlayPauseListener() {
#Override
public void onPlay() {
System.out.println("Play!");
}
#Override
public void onPause() {
System.out.println("Pause!");
}
});
cVideoView.setMediaController(new MediaController(this));
cVideoView.setVideoURI(...);
// or
cVideoView.setVideoPath(...);
// Some other code below...
Finally, you may also declare it in your xml layout and inflate it (as shown above) - just make sure your use <package_name>.CustomVideoView. Example:
<mh.so.CustomVideoView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/custom_videoview" />
You should be able to set your own MediaController.MediaPlayerControl and override pause and start
Could someone help me to create user defined listener interface with some code snippets?
Create a new file:
MyListener.java:
public interface MyListener {
// you can define any parameter as per your requirement
public void callback(View view, String result);
}
In your activity, implement the interface:
MyActivity.java:
public class MyActivity extends Activity implements MyListener {
#override
public void onCreate(){
MyButton m = new MyButton(this);
}
// method is invoked when MyButton is clicked
#override
public void callback(View view, String result) {
// do your stuff here
}
}
In your custom class, invoke the interface when needed:
MyButton.java:
public class MyButton {
MyListener ml;
// constructor
MyButton(MyListener ml) {
//Setting the listener
this.ml = ml;
}
public void MyLogicToIntimateOthers() {
//Invoke the interface
ml.callback(this, "success");
}
}
please do read observer pattern
listener interface
public interface OnEventListener {
void onEvent(EventResult er);
// or void onEvent(); as per your need
}
then in your class say Event class
public class Event {
private OnEventListener mOnEventListener;
public void setOnEventListener(OnEventListener listener) {
mOnEventListener = listener;
}
public void doEvent() {
/*
* code code code
*/
// and in the end
if (mOnEventListener != null)
mOnEventListener.onEvent(eventResult); // event result object :)
}
}
in your driver class MyTestDriver
public class MyTestDriver {
public static void main(String[] args) {
Event e = new Event();
e.setOnEventListener(new OnEventListener() {
public void onEvent(EventResult er) {
// do your work.
}
});
e.doEvent();
}
}
I have created a Generic AsyncTask Listener which get result from AsycTask seperate class and give it to CallingActivity using Interface Callback.
new GenericAsyncTask(context,new AsyncTaskCompleteListener()
{
public void onTaskComplete(String response)
{
// do your work.
}
}).execute();
Interface
interface AsyncTaskCompleteListener<T> {
public void onTaskComplete(T result);
}
GenericAsyncTask
class GenericAsyncTask extends AsyncTask<String, Void, String>
{
private AsyncTaskCompleteListener<String> callback;
public A(Context context, AsyncTaskCompleteListener<String> cb) {
this.context = context;
this.callback = cb;
}
protected void onPostExecute(String result) {
finalResult = result;
callback.onTaskComplete(result);
}
}
Have a look at this , this question for more details.
There are 4 steps:
1.create interface class (listener)
2.use interface in view 1 (define variable)
3.implements interface to view 2 (view 1 used in view 2)
4.pass interface in view 1 to view 2
Example:
Step 1: you need create interface and definde function
public interface onAddTextViewCustomListener {
void onAddText(String text);
}
Step 2: use this interface in view
public class CTextView extends TextView {
onAddTextViewCustomListener onAddTextViewCustomListener; //listener custom
public CTextView(Context context, onAddTextViewCustomListener onAddTextViewCustomListener) {
super(context);
this.onAddTextViewCustomListener = onAddTextViewCustomListener;
init(context, null);
}
public CTextView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CTextView(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CTextView(Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
public void init(Context context, #Nullable AttributeSet attrs) {
if (isInEditMode())
return;
//call listener
onAddTextViewCustomListener.onAddText("this TextView added");
}
}
Step 3,4: implements to activity
public class MainActivity extends AppCompatActivity implements onAddTextViewCustomListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get main view from layout
RelativeLayout mainView = (RelativeLayout)findViewById(R.id.mainView);
//create new CTextView and set listener
CTextView cTextView = new CTextView(getApplicationContext(), this);
//add cTextView to mainView
mainView.addView(cTextView);
}
#Override
public void onAddText(String text) {
Log.i("Message ", text);
}
}
Create listener interface.
public interface YourCustomListener
{
public void onCustomClick(View view);
// pass view as argument or whatever you want.
}
And create method setOnCustomClick in another activity(or fragment) , where you want to apply your custom listener......
public void setCustomClickListener(YourCustomListener yourCustomListener)
{
this.yourCustomListener= yourCustomListener;
}
Call this method from your First activity, and pass the listener interface...
In the year of 2018, there's no need for listeners interfaces. You've got Android LiveData to take care of passing the desired result back to the UI components.
If I'll take Rupesh's answer and adjust it to use LiveData, it will like so:
public class Event {
public LiveData<EventResult> doEvent() {
/*
* code code code
*/
// and in the end
LiveData<EventResult> result = new MutableLiveData<>();
result.setValue(eventResult);
return result;
}
}
and now in your driver class MyTestDriver:
public class MyTestDriver {
public static void main(String[] args) {
Event e = new Event();
e.doEvent().observe(this, new Observer<EventResult>() {
#Override
public void onChanged(final EventResult er) {
// do your work.
}
});
}
}
For more information along with code samples you can read my post about it, as well as the offical docs:
When and why to use LiveData
Official docs
In Android,you can create an interface such as Listener,and your Activity implements it,but i don't think it is a good idea.
if we have many components to listen the changes of their state,we can create a BaseListener implements interface Listener,and use type code to handle them.
we can bind the method when we create XML file,for example:
<Button
android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button4"
android:onClick="Btn4OnClick" />
and the source code:
public void Btn4OnClick(View view) {
String strTmp = "点击Button04";
tv.setText(strTmp);
}
but i don't think it is a good idea...
I have done it something like below for sending my model class from the Second Activity to First Activity. I used LiveData to achieve this, with the help of answers from Rupesh and TheCodeFather.
Second Activity
public static MutableLiveData<AudioListModel> getLiveSong() {
MutableLiveData<AudioListModel> result = new MutableLiveData<>();
result.setValue(liveSong);
return result;
}
"liveSong" is AudioListModel declared globally
Call this method in the First Activity
PlayerActivity.getLiveSong().observe(this, new Observer<AudioListModel>() {
#Override
public void onChanged(AudioListModel audioListModel) {
if (PlayerActivity.mediaPlayer != null && PlayerActivity.mediaPlayer.isPlaying()) {
Log.d("LiveSong--->Changes-->", audioListModel.getSongName());
}
}
});
May this help for new explorers like me.
Simple method to do this approach. Firstly implements the OnClickListeners in your Activity class.
Code:
class MainActivity extends Activity implements OnClickListeners{
protected void OnCreate(Bundle bundle)
{
super.onCreate(bundle);
setContentView(R.layout.activity_main.xml);
Button b1=(Button)findViewById(R.id.sipsi);
Button b2=(Button)findViewById(R.id.pipsi);
b1.SetOnClickListener(this);
b2.SetOnClickListener(this);
}
public void OnClick(View V)
{
int i=v.getId();
switch(i)
{
case R.id.sipsi:
{
//you can do anything from this button
break;
}
case R.id.pipsi:
{
//you can do anything from this button
break;
}
}
}