I'm working on Android Studio and OpenGL ES.
I have successed in making a triangle appear, but I have no idea how to show it in a limited space(i.e 300dp x 300dp).
gLView = new MyGLSurfaceView(this);
setContentView(gLView);
I think setContentView(R.activity.something); and setting a GLSurfaceView in the activity (with layout size:300dp x 300dp) should work, but don't know how.
You can create layout with surfaceView, for example activity_gl.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
tools:context=".activities.OpenGLActivity">
<com.app.LimitedSurfaceView
android:id="#+id/oglView"
android:layout_width="300dp"
android:layout_height="300dp"/>
<!-- other elements -->
</androidx.constraintlayout.widget.ConstraintLayout>
And create LimitedSurfaceView class:
package com.app;
public class LimitedSurfaceView extends GLSurfaceView {
private SceneRenderer renderer;
public LimitedSurfaceView(Context context) {
super(context);
}
public LimitedSurfaceView(Context context, AttributeSet attributes) {
super(context, attributes);
}
public void init(Context context) {
setPreserveEGLContextOnPause(true);
setEGLContextClientVersion(2); // or setEGLContextClientVersion(3)
renderer = new SceneRenderer(context);
setRenderer(renderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
...
}
}
Then in OpenGLActivity class initialize limitedSurfaceView:
package com.app.activities
public class OpenGLActivity extends AppCompatActivity {
private LimitedSurfaceView limitedSurfaceView;
#Override
protected void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_gl);
limitedSurfaceView = findViewById(R.id.oglView);
limitedSurfaceView.init(this.getApplicationContext());
...
}
}
Result:
Related
I have generated simple black with square corners for QR code using com.google.zxing:core:3.3.3.
I want to customize QR code appearance like Instagram.
This library is used at many places https://github.com/scola/Qart
How to make square edges rounded? like below image :
You can create custom class like
private static class CustomViewFinderView extends ViewFinderView {
public final Paint PAINT = new Paint();
public CustomViewFinderView(Context context) {
super(context);
init();
}
public CustomViewFinderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// paint initialization
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Here you can draw your view using canvas with edges
}
}
After that while you initialize your ZXingScannerView add your custom view in createViewFinderView method.
ZXingScannerView mScannerView = new ZXingScannerView(this) {
#Override
protected IViewFinder createViewFinderView(Context context) {
return new CustomViewFinderView(context);
}
};
I read other questions on this, but I feel like my architecture is a bit different, so I'm posting.
I have a game with one MainActivity and multiple views. Basically, there is one LinearLayout that fills MainActivity, and different views are set on the layout depending on the state. For example, menuState (menuView), gameState (gameView), gameOverState (gameOverView).
In my BattleView (which extends SurfaceView), I tried to implement a game loop. However, my BattleView cannot implement a Callback due to the fact getHolder() returns null.
How would I go on about fixing this?
public class MainActivity extends AppCompatActivity {
GameScreen gs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.init();
}
private void init(){
this.gs = new GameScreen(this);
this.hideSystemUI(this.gs);
setContentView(this.gs);
}
Then my GameScreen class contains BattleView class, which is called when appropriate.
public GameScreen(Context context){
super(context);
this.init();
}
private void init(){
this.ms = new MapScreen(this.getContext(), this);
((MainActivity)this.getContext()).hideSystemUI(this.ms);
this.addView(this.ms);
}
private void newMapScreen(){
this.ms = new MapScreen(this.getContext(), this);
}
public void addBattleScreen(BattleScreen bs){
//this.bs = new BattleScreen(this.getContext(), ms);
this.removeView(this.ms);
this.bs = bs;
((MainActivity)this.getContext()).hideSystemUI(this.bs);
this.addView(this.bs);
}
Well.. BattleScreen contains BattleView class and is initialized there. Then, BattleView class
public BattleView(Context context, int monsterNumber, Hero hero){
super(context);
this.gameLoopInit();
this.setBackgroundImage();
}//end
private void gameLoopInit(){
holder = getHolder(); <------------- ERROR (null)
System.out.println(holder);
holder.addCallback(this);
}
I wonder how Android OnClik Listener works? What Pattern is it? Observer?
I cant imagine how I can Implement it in my App! It needs to be a custom implementation because I want to do it with my Objects not with views.
So how can I achieve to call obj.setOnClickListener(new Class(){});
in my code?
I mean ok I could have a methode in my baseclass from which the derived classes implement and then just havin a static ArrayList or so. But how can I add new Classes to this List at runtime?
The definiton of this class OnClickListener(){} is strange.
How is it possible to define an existing class and overriding a method?
My Java is not that good never done this...
EDIT: THIS QUESTION IS NOT ABOUT HOW TO USE ONCLICKLISTENER. I KNOW HOW TO USE THAT...
What i want:
I want a Super Class having an implementation of a method like this:
public void setMyOnclickListener(MyOnClickListener myListener)
{
//magic code
}
and now I want to have an Object of this class lets call it
Subclass obj;
and now I want to do this:
obj.setMyOnClickLister(new MyOnClickListener()
{
//defined method at runtime
public void aDefinedMethod()
{
//here goes in some code
}
});
how can I have a method with a class as a parameter which only exist as an anonymous class?
EDIT2:
Ok I get it OnClickListener is just an Interface -.- not a class defintion
That was my confusion!!!
Each View contains ListenerInfo static class which holds callbacks, OnClickListener too actually.
How it works?
System always holds all views on screen.
When user tap on screen we have a recursive foreach cycle :
switch(event) {
...
case ON_CLICK:
process(ViewRoot);
}
void process(View view) {
for(View view : view.getChilds()) {
if(view instanceOf ViewGroup && ((ViewGroup)view).getChildCount() > 0) {
process(view);
}
if(view.getListenerInfo().mOnClickListener != null)
view.getListenerInfo().mOnClickListener.onClick(view)
}
}
When you call setOnClickListener you actually say "hey Android! here it callback. And when user make click, please use it."
View.class also have getListenerInfo method which returns ListenerInfo object.
System use this method to dispatch events.
So no Observer pattern here. It just simple check of existing callback.
you need to initialize your object (button) first
public class SomeActivity {
...
private Button subButton1, subButton2;
...
protected void onCreate(Bundle savedInstanceState) {
...
init();
}
private void init() {
subButton1 = (Subclass) findViewById(R.id.home_button1);
subButton2 = (Subclass) findViewById(R.id.home_button2);
}
// next is the onClickListener
private void init() {
...
subButton1.setOnClickListener(new MyOnClickListener() {
#Override
public void myOnClick(View v) {
System.out.println("Your own on click 1");
Toast.makeText(HomeActivity.this, "Your own on click 1", Toast.LENGTH_SHORT).show();
}
});
subButton2.setOnClickListener(new MyOnClickListener() {
#Override
public void myOnClick(View v) {
System.out.println("Your own on click 2");
Toast.makeText(HomeActivity.this, "Your own on click 2", Toast.LENGTH_SHORT).show();
}
});
}
private void methodCall() {
// some more code...
}
// Subclass
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Button;
/**
* Created by roelsuntjens on 01-10-15.
*/
public class Subclass extends Button {
public Subclass(Context context) {
super(context);
}
public Subclass(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Subclass(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public Subclass(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public void setOnClickListener(MyOnClickListener l) {
super.setOnClickListener(l);
}
#Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
}
}
// MyOnClickListener
import android.view.View;
/**
* Created by roelsuntjens on 01-10-15.
*/
public abstract class MyOnClickListener implements View.OnClickListener {
public MyOnClickListener() {
}
public abstract void myOnClick(View v);
#Override
public void onClick(View v) {
myOnClick(v);
}
}
// In XML I used this:
<View3D.Subclass
android:id="#+id/home_button1"
android:layout_width="match_parent"
android:text="Button1"
android:layout_height="wrap_content" />
<View3D.Subclass
android:id="#+id/home_button2"
android:layout_width="match_parent"
android:text="Button2"
android:layout_height="wrap_content" />
You can implement onClickListener like that by implementing interface OnClickListener.
Set to your button on setOnClickListner(this) in your activity will listening the click event on the onClick method.
You can also create your on listener by declaring a private OnClickListener like that :
private OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View view) {
// Click occurs, do something
}
};
Then set button.setOnClickListener(listener);
It's very easy...just in your activity_main.xml layout create a button
like this
<Button
android:id="#+id/btnTake"
android:layout_width="wrap_content"
// android:onClick="onClick" (It will automatically create the method if u use onclic)//
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
Now just call the button with its id(IF u r not writing android:onClick="onClick" )
now in Main Activity do this
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnTack = (Button) findViewById(R.id.btnTakePic);
btnTack.setOnClickListener(this);
//call intent or do what u want
Now do what ever you want to do..
I am having trouble sending info from a surfaceView class to its parent class
the overlay activity sets its view as a drawing panel:
public class Overlay extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_Overlay);
drawingPanel dPanel = new drawingPanel(this);
setContentView(dPanel);
}
}
then in the drawing panel:
public class drawingPanel extends SurfaceView implements SurfaceHolder.Callback {
Context context = context;
public Player(Context context, int num) throws ClassNotFoundException, IOException {
super(context);
this.context = context;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
}
public boolean onTouchEvent(MotionEvent e){
if(e.getAction()==MotionEvent.ACTION_DOWN){
//send info to Overlay that drawingPanel was touched
}
}
}
When surfaceView is touched, I want to send that info to Overlay. I can't simply use onTouchEvent in the Overlay activity because I need to draw stuff with drawingPanel. My main goal is to hide/show the action bar when the screen is touched while using a surfaceView. if there is another way to achieve that, please state so below.
Try adding this line to onCreate method of your Overlay class
dPanel.setActivity(this);
And implementing setActivity() in the drawingPanel class like this:
public void setActivity(Activity overlayActivity) {
mActivity = overlayActivity;
}
This way, you can use mActivity to reference your Activity and call public methods to "hide/show the action bar", like:
mActivity.getActionBar().hide();
and,
mActivity.getActionBar().show();
I want to get user input for my OpenGL ES 2.0 application, but there are 2 problems:
1) How can I bring the software keyboard to the front of my app?
2) How can I catch input from it?
I tried to use this:
//OpenGL ES 2.0 view class
public class OGLES2View extends GLSurfaceView
{
private static final int OGLES_VERSION = 2;
private static Handler softKeyboardHandler;
private final static int SHOW_IME_KEYBOARD = 0;
private final static int HIDE_IME_KEYBOARD = 1;
private static EditText textEdit;
private static InputMethodManager imm;
private void setSoftKeyboardHandler()
{
softKeyboardHandler = new Handler()
{
public void handleMessage(Message msg)
{
switch(msg.what)
{
case SHOW_IME_KEYBOARD:
textEdit.requestFocus();
imm.showSoftInput(textEdit,inputMethodManager.SHOW_IMPLICIT);//Nothing happens
Log.i("GLVIEW","SHOW KEYBOARD");
break;
case HIDE_IME_KEYBOARD:
imm.hideSoftInput(textEdit, 0);
Log.i("GLVIEW","HIDE KEYBOARD");
break;
default:
break;
}
}
};
}
public OGLES2View(Context context)
{
super(context);
textEdit = new EditText(context);
setEGLContextClientVersion(OGLES_VERSION);
setRenderer(new OGLES2Renderer());
imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
setSoftKeyboardHandler();
}
public static void showIMEKeyboard()
{
softKeyboardHandler.sendEmptyMessage(SHOW_IME_KEYBOARD);
}
public static void hideIMEKeyboard()
{
softKeyboardHandler.sendEmptyMessage(HIDE_IME_KEYBOARD);
}
//In main activity class
private GLSurfaceView ogles2SurfaceView = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//...
ogles2SurfaceView = new OGLES2View(this);
setContentView(ogles2SurfaceView);
}
Handler gets messages, but I got no software keyboard.
To catch text, I wrote some class:
public class TextInputWatcher implements TextWatcher
and:
textEdit.addTextChangedListener(/*TextInputWatcher instance*/);
Or extend a TextEdit so it catches inputed text on back or enter key.
P.S. I got a tablet - transformer, so there is a hardware keyboard attached. I tried with it and without, but no difference. So bonus question - if there is a hardware keyboard will it prevent a software keyboard from popping up and how can input be gotten from it then?.
Show keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Hide keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
I made 2d game. I think you have the same problem like me before. Try this:
class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {
private static DrawThread _thread;
public DrawingPanel(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
_thread = new DrawThread(getHolder(), this);
}
....
Layout 'gameview':
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- YOUR SURFACE -->
<com.yourcompany.DrawingPanel android:id="#+id/surfaceView" android:layout_width="fill_parent"
android:layout_height="fill_parent"></com.yourcompany.DrawingPanel>
<!-- YOUR BUTTONS -->
<RelativeLayout android:id="#+id/controlPanel" android:layout_width="fill_parent" android:orientation="horizontal"
android:layout_height="fill_parent" >
<RelativeLayout android:layout_width="50px" android:orientation="vertical"
android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_alignParentLeft="true">
<Button android:id="#+id/leftButton" android:layout_width="wrap_content"
android:layout_height="50px" android:background="#xml/button_left_state"/>
<Button android:id="#+id/upgradeButton" android:layout_width="wrap_content"
android:layout_below="#id/leftButton"
android:layout_height="50px" android:background="#xml/button_upgrade_state"/>
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
Then you should set content in game activity like below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameview);
...
Hope It helps you.