can a SurfaceView be rendered inside a RecyclerView
what i am trying to do is make a Grid of SurfaceView's
#Keep
public class NativeView {
String TAG = "EglSample";
public static native void nativeOnStart();
public static native void nativeOnResume();
public static native void nativeOnPause();
public static native void nativeOnStop();
// this is part of graphics manager
public native void nativeSetSurface(Surface surface);
View surfaceView = null;
SurfaceHolderCallback surfaceHolderCallback = null;
public NativeView(Context context) {
System.loadLibrary("nativeegl");
surfaceHolderCallback = new SurfaceHolderCallback();
surfaceView = new View(surfaceHolderCallback, context);
}
class View extends SurfaceView {
public View(SurfaceHolder.Callback callback, Context context) {
super(context);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getHolder().addCallback(callback);
}
public View(SurfaceHolder.Callback callback, Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
super(context, attrs, defStyle, defStyleRes);
getHolder().addCallback(callback);
}
}
class SurfaceHolderCallback implements SurfaceHolder.Callback {
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
nativeSetSurface(holder.getSurface());
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
nativeSetSurface(null);
}
}
}
public ViewGroup onViewRequest(Context mContext) {
if (context == null) context = mContext;
if (n == null) n = new NativeView(context);
Log.i(n.TAG, "onViewRequest(Activity, Context)");
// build layout
RelativeLayout rel = new RelativeLayout(context);
rel.addView(n.surfaceView);
n.surfaceView.setOnClickListener(new MyListener());
// set text
TextView text = new TextView(context);
text.setText("Hello World! Try clicking the screen");
text.setTextSize(60f);
text.setTextColor(Color.WHITE);
rel.addView(text);
Log.i(n.TAG, "onCreate()");
// build layout
NativeView.nativeOnStart();
NativeView.nativeOnResume();
return rel;
}
full:
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/java/vst/demo/opengl/addons/cube/main.java
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/java/vst/demo/opengl/addons/cube/NativeView.java
as it renders corrupted in a recycler view (text but no surface view) (you can barely make out the white text but the fact that it is there means the view heirarchy IS being drawn)
(set USE_RECYCLER_VIEW = true)
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/VstManager/src/main/java/vst/manager/VstGrid.java#L29
Boolean USE_RECYCLER_VIEW = false;
public LinearLayout getView() {
// this assumes the first available "*\.addons\.*" package
if (!USE_RECYCLER_VIEW) {
VST pkg = mVstMan.loadPackage(mActivity, mVstMan.getPackages(mActivity)[0].packageName, false);
VST.CLASS vstClass = mVstMan.loadClass(pkg, "main");
Object vstClassInstance = mVstMan.newInstance(vstClass, "main");
// android.widget.RelativeLayout cannot be cast to android.widget.LinearLayout
LinearLayout x = new LinearLayout(mActivity);
x.addView((ViewGroup) mVstMan.invokeMethod(
vstClass, vstClassInstance,
"onViewRequest", Context.class,
pkg.activityApplicationContext
)
);
return x;
} else {
if (recyclerViewMain == null)
recyclerViewMain = (LinearLayout) LayoutInflater.from(mActivity.getApplicationContext())
.inflate(R.layout.vst_grid, null, false);
if (recyclerView == null) {
recyclerView = recyclerViewMain
.findViewById(R.id.VstGrid);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
}
if (layoutManager == null) {
// use a linear layout manager
layoutManager = new GridLayoutManager(mActivity, 1);
recyclerView.setLayoutManager(layoutManager);
}
if (mAdapter == null) {
// specify an adapter (see also next example)
mAdapter = new VstGridAdapter(mActivity, mVstMan, mVstUI);
recyclerView.setAdapter(mAdapter);
}
mAdapter.update();
return recyclerViewMain;
}
}
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/VstManager/src/main/java/vst/manager/VstGridAdapter.java#L86
// Create new views (invoked by the layout manager)
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
VST pkg = mVstMan.loadPackage(mActivity, mVstMan.getPackages(mActivity)[0].packageName, false);
VST.CLASS vstClass = mVstMan.loadClass(pkg, "main");
Object vstClassInstance = mVstMan.newInstance(vstClass, "main");
// android.widget.RelativeLayout cannot be cast to android.widget.LinearLayout
LinearLayout x = new LinearLayout(mActivity);
x.addView((ViewGroup) mVstMan.invokeMethod(
vstClass, vstClassInstance,
"onViewRequest", Context.class,
pkg.activityApplicationContext
)
);
return new MyViewHolder(x);
}
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/cpp/RotatingSquares/jniapi.cpp
https://github.com/mgood7123/VSTDEMO/blob/0f5e7063d9ebef5ae5a05f128d548eec712b741f/vstdemoopengladdonscube/src/main/cpp/RotatingSquares/renderer.cpp#L153
meanwhile it renders perfectly fine if NOT in a recycler view (leave USE_RECYCLER_VIEW as false)
why?
apparently in order to get it to display i needed to give the view fixed size layout paramaters: mView.setLayoutParams(new ViewGroup.LayoutParams(500, 500));
Related
I tried to migrate my Chat Bot from ScrollView to a RecyclerView for performance, but unfortunally every method in my Adapter is called correctly but nothing is showed.
My Custom RecyclerView Adapter:
public class ChatViewAdapter extends RecyclerView.Adapter<ChatViewAdapter.ChatViewHolder> {
private LinkedList<ChatBubbleModel> bubbles;
private ViewGroup group;
public ChatViewAdapter() {
this(new LinkedList<ChatBubbleModel>());
}
public ChatViewAdapter(LinkedList<ChatBubbleModel> bubbles) {
this.bubbles = bubbles;
}
public LinkedList<ChatBubbleModel> getBubbles() {
return bubbles;
}
public void addBubble(ChatBubbleModel bubble) {
this.bubbles.add(bubble);
notifyDataSetChanged();
}
#NonNull
#Override
public ChatViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
this.group = parent;
return new ChatViewHolder(new TextView(parent.getContext()));
}
#Override
public void onBindViewHolder(#NonNull ChatViewHolder holder, int position) {
final ChatBubbleModel instance = this.bubbles.get(position);
if (instance.getUserType() == ChatBubbleModel.UserType.USER) {
holder.setTextView(new RightChatBubble(instance.getOwner(), instance.getMessage(), group.getContext()));
} else {
holder.setTextView(new LeftChatBubble(instance.getOwner(), instance.getMessage(), group.getContext()));
}
}
#Override
public int getItemCount() {
return this.bubbles.size();
}
public static class ChatViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
private TextView textView;
public ChatViewHolder(TextView v) {
super(v);
textView = v;
}
public void setTextView(TextView view) {
this.textView = view;
}
}
}
And in the Fragmnet where I use it:
final View root = inflater.inflate(R.layout.fragment_chatview, container, false);
chatView = root.findViewById(R.id.chatView);
chatView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
chatView.setLayoutManager(layoutManager);
this.chatAdapter = new ChatViewAdapter(new LinkedList<ChatBubbleModel>());
chatView.setAdapter(chatAdapter);
The Impl of the View I use:
public class LeftChatBubble extends androidx.appcompat.widget.AppCompatTextView {
private final static int leftRightPadding = 50;
private final static int topBottomPadding = 20;
public LeftChatBubble(Context context) {
this(context, null, -1);
}
#SuppressLint("SetTextI18n")
public LeftChatBubble(String owner, String text, Context context) {
super(context);
setText(owner + "\n" + text);
setBackground(ContextCompat.getDrawable(context, R.drawable.inset));
setPadding(pixelToDp(leftRightPadding, context), pixelToDp(topBottomPadding, context), pixelToDp(leftRightPadding, context), pixelToDp(topBottomPadding, context));
setTextAlignment(TEXT_ALIGNMENT_VIEW_START);
setTextColor(Color.WHITE);
}
public LeftChatBubble(Context context, #Nullable AttributeSet attrs) {
this(context, attrs, -1);
}
public LeftChatBubble(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setBackground(ContextCompat.getDrawable(context, R.drawable.ic_chatbubleleft));
setPadding(pixelToDp(leftRightPadding, context), pixelToDp(topBottomPadding, context), pixelToDp(leftRightPadding, context), pixelToDp(topBottomPadding, context));
setTextAlignment(TEXT_ALIGNMENT_VIEW_START);
setTextColor(Color.WHITE);
}
private int pixelToDp(int px, Context context) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (px * scale + 0.5f);
}
}
Does anyone have an Idea why there is nothing showed on the device? The Used Layout is correct bc it worked before.
You did not seem to inflate your item view in the onCreateViewHolder like
#NonNull
#Override
public ChatViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
this.group = parent;
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.item_view, parent, false);
return new ChatViewHolder(view);
}
Also, change your ViewHolder args to be a View.
The Problem was that I not created the Correct View Class in onCreate Mathod of Adapter...
But thank you all for your helpful answers.
I have put one recycler view in my project. I want that it will be auto-scroll horizontally. For achieving this I have made one custom class. but I also want that existing functions which I put on my recycler view will also remain.
CustomLinearLayoutManager:
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager (Context context) {
super(context);
}
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CustomLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
final LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
private static final float MILLISECONDS_PER_INCH = 200f;
#Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return CustomLinearLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
#Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
Home Class
private RecyclerView recyclerViewHeaderSlider;
private HeaderSliderAdapter headerSliderAdapter;
private List<Banner> banners;
banners = new ArrayList<>();
headerSliderAdapter = new HeaderSliderAdapter(getActivity(), banners);
recyclerViewHeaderSlider = view.findViewById(R.id.bannerSlider);
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerViewHeaderSlider);
recyclerViewHeaderSlider.setHasFixedSize(true);
recyclerViewHeaderSlider.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
headerSliderAdapter.setOnClick(this);
recyclerViewHeaderSlider.setAdapter(headerSliderAdapter);
I want to implement my custom linear layout manager with Home class.
You can use Runnable to autoscroll Horizontal RV
public void autoScroll(){
speedScroll = 0;
handler = new Handler();
runnable = new Runnable() {
int count = 0;
#Override
public void run() {
if(count == tickerAdapter.getItemCount())
count = 0;
else {
if(count < tickerAdapter.getItemCount()){
rvTicker.smoothScrollToPosition(++count);
handler.postDelayed(this,speedScroll);
}else {
count = 0;
}
}
}
};
handler.postDelayed(runnable,speedScroll);
}
I have a RecyclerView holding CardViews with a favorite button within each card. I would like the favorite button to only be clicked for each specific card. I am currently using a ViewHolder to maintain each of the components in each card and the favorite button is one of those components.
How can I use an onClick() defined in a separate class within the ViewHolder?
Using this code currently only actives the onTouchEvent() for the favoriteButton
viewHolder.favoriteButton.setOnClickListener(new LikeButtonView(mContext));
AppAdapter.java
public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> {
PackageManager packageManager;
private List<App> apps;
private int rowLayout;
private Context mContext;
public AppAdapter(List<App> apps, int rowLayout, Context context) {
this.apps = apps;
this.rowLayout = rowLayout;
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
packageManager = this.mContext.getPackageManager();
View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowLayout, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
App appObject = apps.get(i);
viewHolder.appName.setText(appObject.getApplicationName());
viewHolder.versionNumber.setText(String.valueOf(appObject.getVersionNumber()));
viewHolder.updateDate.setText(String.valueOf(appObject.getLastUdpateTime()));
viewHolder.appIcon.setImageDrawable(appObject.getAppIcon());
viewHolder.appChangelog.setText(appObject.getChangelogText());
viewHolder.favoriteButton.setOnClickListener(new LikeButtonView(mContext));
}
LikeButtonView.java
public class LikeButtonView extends FrameLayout implements View.OnClickListener {
private static final DecelerateInterpolator DECCELERATE_INTERPOLATOR = new DecelerateInterpolator();
private static final AccelerateDecelerateInterpolator ACCELERATE_DECELERATE_INTERPOLATOR = new AccelerateDecelerateInterpolator();
private static final OvershootInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(4);
#Bind(R.id.ivStar)
ImageView ivStar;
private boolean isChecked;
private AnimatorSet animatorSet;
public LikeButtonView(Context context) {
super(context);
init();
}
public LikeButtonView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LikeButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LikeButtonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
LayoutInflater.from(getContext()).inflate(R.layout.view_like_button, this, true);
ButterKnife.bind(this);
setOnClickListener(this);
}
#Override
public void onClick(View v) {
isChecked = !isChecked;
ivStar.setImageResource(isChecked ? R.drawable.ic_star_rate_on : R.drawable.ic_star_rate_off);
if (animatorSet != null) {
animatorSet.cancel();
}
if (isChecked) {
ivStar.animate().cancel();
ivStar.setScaleX(0);
ivStar.setScaleY(0);
animatorSet = new AnimatorSet();
ObjectAnimator starScaleYAnimator = ObjectAnimator.ofFloat(ivStar, ImageView.SCALE_Y, 0.2f, 1f);
starScaleYAnimator.setDuration(350);
starScaleYAnimator.setStartDelay(0);
starScaleYAnimator.setInterpolator(OVERSHOOT_INTERPOLATOR);
ObjectAnimator starScaleXAnimator = ObjectAnimator.ofFloat(ivStar, ImageView.SCALE_X, 0.2f, 1f);
starScaleXAnimator.setDuration(350);
starScaleXAnimator.setStartDelay(0);
starScaleXAnimator.setInterpolator(OVERSHOOT_INTERPOLATOR);
animatorSet.playTogether(
starScaleYAnimator,
starScaleXAnimator
);
animatorSet.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationCancel(Animator animation) {
ivStar.setScaleX(1);
ivStar.setScaleY(1);
}
});
animatorSet.start();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ivStar.animate().scaleX(0.7f).scaleY(0.7f).setDuration(150).setInterpolator(DECCELERATE_INTERPOLATOR);
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
boolean isInside = (x > 0 && x < getWidth() && y > 0 && y < getHeight());
if (isPressed() != isInside) {
setPressed(isInside);
}
break;
case MotionEvent.ACTION_UP:
ivStar.animate().scaleX(1).scaleY(1).setInterpolator(DECCELERATE_INTERPOLATOR);
if (isPressed()) {
performClick();
setPressed(false);
}
break;
}
return true;
}
}
It seems setChecked is invoked every time I click the preference and the selected item changes but in the dialog the selected item remains unchanged for some reason. I have no idea what's going on. Relaunching the application can make the selected item change but that's not the expected behavior. :~
Here's the class:
public class IconListPreference extends ListPreference {
private Context mContext;
private LayoutInflater mInflater;
private Drawable[] mEntryIcons = null;
private String mKey;
private int selectedEntry = -1;
public IconListPreference(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public IconListPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs);
mContext = context;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconPreference, defStyle, 0);
int entryIconsResId = a.getResourceId(R.styleable.IconPreference_entryIcons, -1);
if (entryIconsResId != -1) setEntryIcons(entryIconsResId);
mInflater = LayoutInflater.from(context);
mKey = getKey();
a.recycle();
}
public void setEntryIcons(Drawable[] entryIcons) {
mEntryIcons = entryIcons;
}
public void setEntryIcons(int entryIconsResId) {
TypedArray icons_array = mContext.getResources().obtainTypedArray(entryIconsResId);
Drawable[] icon_ids_array = new Drawable[icons_array.length()];
for (int i = 0; i < icons_array.length(); i++) icon_ids_array[i] = icons_array.getDrawable(i);
setEntryIcons(icon_ids_array);
icons_array.recycle();
}
#Override
protected void onPrepareDialogBuilder(Builder builder) {
CharSequence[] entries = getEntries(), entryValues = getEntryValues();
if (entries.length != entryValues.length) throw new IllegalStateException
("ListPreference requires an entries array and an entryValues array which are both the same length");
if (mEntryIcons != null && entries.length != mEntryIcons.length) throw new IllegalStateException
("IconListPreference requires the icons entries array be the same length than entries or null");
IconListPreferenceScreenAdapter iconListPreferenceAdapter = new IconListPreferenceScreenAdapter();
if (mEntryIcons != null) {
String selectedValue = getPreferenceManager().getSharedPreferences().getString(mKey, "");
for (int i = 0; i < entryValues.length; i++) {
if (selectedValue.compareTo((String) entryValues[i]) == 0) {
selectedEntry = i;
break;
}
}
builder.setAdapter(iconListPreferenceAdapter, null);
}
super.onPrepareDialogBuilder(builder);
}
private class IconListPreferenceScreenAdapter extends BaseAdapter {
public int getCount() {
return mEntryIcons.length;
}
class CustomHolder {
private CheckedTextView text = null;
CustomHolder(View row, int position) {
text = (CheckedTextView) row.findViewById(android.R.id.text1);
text.setText(getEntries()[position]);
text.setChecked(selectedEntry == position);
if (mEntryIcons != null)
text.setCompoundDrawablesWithIntrinsicBounds(mEntryIcons[position], null, null, null);
}
}
public Object getItem(int position) {
return getEntries()[position];
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) convertView = mInflater.inflate(Resources.getSystem()
.getIdentifier("select_dialog_singlechoice_holo", "layout", "android"), parent, false);
CustomHolder holder;
final int p = position;
holder = new CustomHolder(convertView, position);
convertView.setTag(holder);
convertView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
v.requestFocus();
getDialog().dismiss();
IconListPreference.this.callChangeListener(getEntryValues()[p]);
SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit();
editor.putString(mKey, getEntryValues()[p].toString());
selectedEntry = p;
editor.apply();
}
});
return convertView;
}
}
}
And res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="IconPreference">
<attr name="entryIcons" format="reference" />
</declare-styleable>
</resources>
EDIT: Updated my code with a bugfix, but still don't work sthough. A temporary solution found: invoke setValue((String) newValue) in OnPreferenceChangeListener.onPreferenceChange.
OK I finally get it. You need to do the following to make your customized preference work:
callChangeListener before setting user-supplied values;
notifyChanged if you need to update user interface, i.e. whenever value changes.
I am using webview in android to play a video. The problem is that video is playing once. I have seen some answers about how to fix it, but still not working. Here's my code:
public class MyChromeClient extends WebChromeClient implements
OnCompletionListener, OnErrorListener {
private Activity _activity;
private VideoView mCustomVideoView;
private LinearLayout mContentView;
private FrameLayout mCustomViewContainer;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT, Gravity.CENTER);
public MyChromeClient(Activity context) {
super();
_activity = context;
}
#Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
if (view instanceof FrameLayout) {
FrameLayout frame = (FrameLayout) view;
if (frame.getFocusedChild() instanceof VideoView) {
mCustomVideoView = (VideoView) frame.getFocusedChild();
frame.removeView(mCustomVideoView);
_activity.setContentView(mCustomVideoView);
mCustomVideoView.setOnCompletionListener(this);
mCustomVideoView.setOnErrorListener(this);
mCustomVideoView.start();
}
}
}
public void onHideCustomView() {
if (mCustomVideoView == null)
return;
// Hide the custom view.
mCustomVideoView.setVisibility(View.GONE);
// Remove the custom view from its container.
mCustomViewContainer.removeView(mCustomVideoView);
mCustomVideoView = null;
mCustomViewContainer.setVisibility(View.GONE);
mCustomVideoView.stopPlayback();
mCustomViewCallback.onCustomViewHidden();
// Show the content view.
mContentView.setVisibility(View.VISIBLE);
}
public void onCompletion(MediaPlayer mp) {
//Intent intent = new Intent(_activity, _activity.getClass());
//intent.setClass(_activity, _activity.getClass());
//_activity.startActivity(intent);
//_activity.finish();
}
public boolean onError(MediaPlayer mp, int what, int extra) {
return true;
}
}
try this
add this in show method
WebChromeClient.CustomViewCallback CustomViewCallback; mCustomViewCallback = callback;
then in hide method...
mCustomViewCallback.onCustomViewHidden(); mCustomViewCallback = null; HTML5WebView.this.goBack();
EDIT :-
public class HTML5WebView extends WebView {
static final String LOGTAG = "HTML5WebView";
private void init(Context context) {
mContext = context;
Activity a = (Activity) mContext;
mLayout = new FrameLayout(context);
mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(a).inflate(R.layout.custom_screen, null);
mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.main_content);
mCustomViewContainer = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.fullscreen_custom_content);
mLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
// Configure the webview
WebSettings s = getSettings();
s.setBuiltInZoomControls(true);
s.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
s.setUseWideViewPort(true);
s.setLoadWithOverviewMode(true);
s.setSaveFormData(true);
s.setJavaScriptEnabled(true);
mWebChromeClient = new MyWebChromeClient();
setWebChromeClient(mWebChromeClient);
setWebViewClient(new WebViewClient());
setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
s.setDomStorageEnabled(true);
mContentView.addView(this);
}
public HTML5WebView(Context context) {
super(context);
init(context);
}
public HTML5WebView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public HTML5WebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public FrameLayout getLayout() {
return mLayout;
}
public boolean inCustomView() {
return (mCustomView != null);
}
public void hideCustomView() {
mWebChromeClient.onHideCustomView();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if ((mCustomView == null) && canGoBack()){
goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
private class MyWebChromeClient extends WebChromeClient {
private Bitmap mDefaultVideoPoster;
private View mVideoProgressView;
FrameLayout frame;
#Override
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
{
HTML5WebView.this.setVisibility(View.GONE);
isVideoPlaying = true;
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomViewContainer.addView(view);
mCustomView = view;
frame = (FrameLayout) mCustomView;
mCustomViewCallback = callback;
VideoView mVideoView;
if(frame.getFocusedChild() instanceof VideoView){
mVideoView = (VideoView) frame.getFocusedChild();
}
mCustomViewContainer.setVisibility(View.VISIBLE);
}
#Override
public void onHideCustomView() {
if (mCustomView == null)
return;
// Hide the custom view.
mCustomView.setVisibility(View.GONE);
// Remove the custom view from its container.
mCustomViewContainer.removeView(mCustomView);
mCustomView = null;
mCustomViewContainer.setVisibility(View.GONE);
mCustomViewCallback.onCustomViewHidden();
mCustomViewCallback = null;
HTML5WebView.this.setVisibility(View.VISIBLE);
HTML5WebView.this.goBack();
}
}
}
I would like to offer an alternative, it may not be perfect, but from a web programming point of view, after beating my head against this for some time, the trick was to covert the video to base64 and the feed it to the source tag (jquery in my case). If it isn't in the assets folder it can't get confuse!