I'm trying to create a square layout for a widget.
I have the following layout class:
package com.trollhammaren;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;
public class SquareLayout extends LinearLayout {
// constructors
public SquareLayout(Context context) {
super(context);
}
public SquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
// methods
#Override
protected void onMeasure(int width, int height) {
Log.v("widget", "resized");
super.onMeasure(width, height);
}
}
And the following xml:
<?xml version="1.0" encoding="utf-8"?>
<com.trollhammaren.SquareLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dip"
android:background="#drawable/myshape" >
</com.trollhammaren.SquareLayout>
Instead of a square I see a rectangle widget with the text "Problem loading widget". When I place the widget I see the following message in logcat:
Error inflating AppWidget AppWidgetProviderInfo(provider=ComponentInfo{com.trollhammaren.wakeonlandroid/com.trollhammaren.wakeonlandroid.WidgetProvider}): android.view.InflateException: Binary XML file line #2: Error inflating class com.trollhammaren.SquareLayout
If I change the layout to LinearLayout, I do see a normal LinearLayout, but it's not square.
What am I doing wrong?
Inside of the Widget you can only have Views and Layouts that are tagged as RemoteViews. So I don't think you can send your own custom class over to the AppWidget context. It has to be done with only the views within the OS version that are tagged this way.
To be clear the way these work, the context which hosts the Widget is not your process. So the AppWidget's context basically sends everything via an RPC like mechanism from your app to another context's view. If it supported custom widgets, that would allow you basically to send arbitrary code to the other apps process and assume a lot more permissions than I bet they would really like you to have. Plus it would be nasty for the IPC, since you would need to parcel the entire class hierarchy and load it in a separate classloader and all that stuff just to guarantee dependancies are upheld.
Related
I'm investigating how to customize Digits within my app in the following ways:
Theming: The documentation show how to change the color theming of the form, but no how to (if possible) change the view layout or add/remove view elements. Can I change the text of the DigitsAuthButton? Another very important example would be to change the functionality of the android os back button.
Flow: I'd like to customize the flow of authentication. For example, when a phone number is not valid in my server, the Android user is directed to a new screen (not necessarily a sign up/create account). I would also like to implement custom error handling (i.e. custom dialogue when the confirmation code is incorrect, etc.)
I'd love feedback from anyone with experience using Digits on if it is the correct tool for what I want to do and, if so, how I would approach these customizations.
You can check out Cannonball Sample project, which is open source.
To change the text of the DigitsAuthButton, you can add a customized Digits button by extending the DigitsAuthButton:
public class DigitsRegisterButton extends DigitsAuthButton {
public DigitsRegisterButton(Context c) {
super(c);
init();
}
public DigitsRegisterButton(Context c, AttributeSet attrs) {
super(c, attrs);
init();
}
public DigitsRegisterButton(Context c, AttributeSet attrs, int defStyle) {
super(c, attrs, defStyle);
init();
}
private void init() {
if (isInEditMode()) {
return;
}
setBackgroundResource(R.drawable.digits_button_bg);
// Modifying the text here..
setText(getResources().getString(R.string.digits_register_text));
setTextColor(getResources().getColor(R.color.theme_color));
}
}
And then you can use and customize this inside your layouts as:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.pinchat.pinchat.view.DigitsRegisterButton
android:id="#+id/signup_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/digits_button_bg"
android:text="#string/digits_register_text"
android:textColor="#color/theme_color"
android:textSize="#dimen/digits_register_btn_text"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:drawableStart="#drawable/ic_signin_phone"
android:drawableLeft="#drawable/ic_signin_phone"/>
</RelativeLayout>
I haven't experimented with the second query of yours. But since the code is open source, you can have a look at it - Digits on GitHub. This repository also has a sample which is worth looking at.
Most easy way to customize the DigitsAuthButtonbutton would be following below:
Create a new background image and name it as dgts__digits_btn.png ==> this would replace the bg image of digiAuth button.
Change padding around the DigitsAuthButton button by adding tw__login_btn_drawable_padding attribute in dimens.xml
Change default DigitsAuthButton button text by adding string entry with name "dgts__login_digits_text" in strings.xml
Change text size by adding "tw__login_btn_text_size" in dimens.xml
DigitsAuthButton Button padding by adding "tw__login_btn_right_padding" and dimens.xml
Hope this helps.
Before you jump with negative comments/votes, I will specify that I have read every question on `Stackoverflow regarding this topic, and have applied almost all the solutions, but still I have not succeeded applying it entirely.
So, I am asking this question, because almost all the answers I found are for like 4-5 years ago, and I was wondering if there are better solutions now.
I repeat my question: Is there a better way than those listed to override the whole font family in the whole app to only 1 font? (All the views used in the app)?
Thanks in advance!
Cheers!
The best way is still to put your .ttf or .otf font file in the assets folder. Then derive a custom TextView class and fix its' font once and for all so that you don't have to call setTypeface() everywhere.
That is all.
Custom TextView Java Class
Put this class in com.util package
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
public class CustomTextViewRegular extends TextView {
public CustomTextViewRegular(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public CustomTextViewRegular(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public CustomTextViewRegular(Context context) {
super(context);
init(null);
}
private void init(AttributeSet attrs) {
if (attrs != null) {
// Set type face
Typeface myTypeface = Typeface.createFromAsset(getContext()
.getAssets(), "Helvetica_Neue.ttf");
setTypeface(myTypeface);
}
}
}
You must have Helvetica_Neue.ttf in assets folder, you can use other font as well.
How to use in xml
<com.util.CustomTextViewRegular
android:id="#+id/txtCustom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:textColor="#727272"
android:textSize="20dip" />
If you want to change font than you have to just change font type in Java class only.
Done
I have found no work-arounds for setting one font on the app, so I resorted in calling setTypeface() for each view in each of the fragment/activities. Thanks, and I apologize for the long time in which i did not answer! I well deserve the downvotes, hehe.
Cheers everyone! I will pay more attention to asking questions and my behavior towards the users answering them in the future.
I want use the native sdk interface layout, (How a normal app) to design my game menu, and link it to the BaseGameActivity, or GameScene, I know how to design the interface using sdk native, but I dont know how implement it on andengine :S
I cant find any solution, I will hope anybody can help me to find the best method, or the way to use these.
Sorry for my bad english.
More info: I know how to add a little framelayout on my baseactivity, but I can a set of menus (2/3) and that you can move on it, and enter on the game and exit of the game :)
Sorry my english again
Well, I do this works :)
Only create a normal activity, with the layout etc.. and use the intent.putExtra(); to send a particular info to the BaseGameActivy, Then, on onCreateResources() I set a serie of conditions to determine that I press before, and set the wished scene.
Sorry my english :)
EDIT: imported tutorials from original website
How to use UI Android SDK with AndEndine
NOTE : You may have filling errors if you change width and heights in these layouts so be carefull (this solution works with fullscreen usage)
XML layout
In your project's directory res/layout create an empty file named themainactivity.xml and put the following content inside.
Notes : Set the attribute tools:context to your application activity name, beginning with a dot (here: .MyMainActivity)
XML layout file: res/layout/themainactivity.xml
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!-- code placed here will be above the AndEngine render -->
</RelativeLayout>
Java class
You just have to specify the IDs in your class.
MyMainActivity.java
package com.example;
import org.andengine.ui.activity.SimpleLayoutGameActivity;
public class MyMainActivity extends SimpleLayoutGameActivity
{
#Override
protected int getLayoutID()
{
return R.layout.themainactivity;
}
#Override
protected int getRenderSurfaceViewID()
{
return R.id.gameSurfaceView;
}
}
Create a custom Android SDK layout in AndEngine
XML layout
WARNING: the root node must be a merge node ! Inside this you can do what you want.
XML layout file: res/layout/my_view.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:text="Dat button" />
</LinearLayout>
</merge>
The controller class
For being able to use your interface you have to link it to the XML view using the inflater service.
NOTE: The UI Java code is compiled when you switch to the WYSIWIG editor so if you don't add the linking code below you won't see the contents of the layout in the activities that use it.
Custom layout: MyView.java
package com.example;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
public class MyView extends LinearLayout
{
public MyView(Context context, AttributeSet attrs)
{
super(context, attrs);
// Link to the XML view
LayoutInflater.from(context).inflate(R.layout.my_view, this, true);
// Link to the XML view (alternative using service, you can delete if you don't need it)
//LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//inflater.inflate(R.layout.my_view, this);
}
}
Reuse in an other activity
Just add this code in the activity layout.
<com.example.MyView
android:id="#+id/myView1"
android:layout_width="100dp"
android:layout_height="wrap_content" />
Edit: I made a demo apk, so you can understand what I mean: http://cl.ly/3g0s1p030j243y0p3m2F
For my application, I want a kind of "Super Power Point", or a keynote (the commercial team will present the product to their customers) using all the Android goodness, gestures, etc... on an Android tablet. As Honeycomb is not yet ready and because we need it before march, we choose some random Froyo Tablet (Archos 101), but my issue is for every tablet/phone I tried.
I made a really great application, but for some animations during the presentation, the customer wanted to use flash animations. Because I couldn't code animations (sort of little movies/ animated graphics) that easily in Android and the lack of time, that seemed to be a good idea.
So, after some search on the Web, I used webview and this code:
WebView mWebView1 = (WebView) findViewById(R.id.webview1);
mWebView1.getSettings().setJavaScriptEnabled(true);
mWebView1.getSettings().setPluginsEnabled(true);
mWebView1.loadUrl("file:///android_asset/graph_01.swf");
This work pretty well, but on every device I tried (Archos 101, Nexus One, Nexus S, Galaxy S, Xperia, Desire, HTC Hero, and really more) every activity with a webview blink, a few milliseconds of black screen, then the animation finally appear.
PS: My layout is quite simple too:
<?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"
>
<WebView android:id="#+id/webview1" android:layout_height="fill_parent"
android:layout_width="fill_parent"></WebView>
</LinearLayout>
Please help me, I cannot imagine I am the only one to face this issue.
Thank a lot for any help. You have all my code and the demo apk.
THIS ANSWER ADDED LATER:
So the problem is that Adobe's Flash Player creates a SurfaceView inside the WebView and there is a delay between the SurfaceView appearing and the Flash engine bothering to draw anything. In that small gap the SurfaceView appears totally black.
The solution I've found is to subclass WebView and add a customized SurfaceView to the view tree. Secondly it is also important to suppress the first draw() call to the Adobe view. The code for my subclassed WebView is as follows:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.webkit.WebView;
import android.widget.AbsoluteLayout;
public class FixAdobeWebView extends WebView {
View whiteView;
private boolean eatenFirstFlashDraw;
public FixAdobeWebView(Context context, AttributeSet attrs) {
super(context, attrs);
whiteView = new WhiteSurfaceView(context);
whiteView.setLayoutParams(new AbsoluteLayout.LayoutParams(800, 480, 0, 0));
addView(whiteView);
}
private class WhiteSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
public WhiteSurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Canvas canvas = holder.lockCanvas();
if (canvas != null) {
canvas.drawColor(Color.WHITE);
holder.unlockCanvasAndPost(canvas);
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) { }
#Override
public void surfaceDestroyed(SurfaceHolder holder) { }
}
//
// Override drawChild to eat the first draw of the FlashPaintSurface
//
#Override
protected boolean drawChild (Canvas canvas, View child, long drawingTime) {
if (!eatenFirstFlashDraw && child.getClass().getName().equals("com.adobe.flashplayer.FlashPaintSurface")) {
eatenFirstFlashDraw = true;
return true;
}
return super.drawChild(canvas, child, drawingTime);
}
}
The layout XML should declare an instance of this class, i.e. :
<?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"
android:background="#android:color/white"
>
<org.test.FixAdobeWebView android:id="#+id/webview1"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
</LinearLayout>
On my Nexus One running CM6.1 this works perfectly in that the WebView appears as solid white until the Flash SurfaceView starts drawing. You will probably need to adapt it a bit, e.g. get rid of the hardcoded 800x480 dimensions, and also destroy the white SurfaceView once it's no longer needed.
ORIGINAL (WRONG) ANSWER:
Looks like Adobe are to blame for this one.
The least awful workaround I've found so far is to :
Make the background of the WebView's parent a compatible colour (i.e. white).
Hide the WebView initially.
Wait until you get the page loaded event, and then queue a runnable to show the WebView after a one second delay.
It means you get a guaranteed one second delay before you can see anything, but it's less jarring than that horrible black flash afaik.
Layout:
<?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"
android:background="#android:color/white"
>
<WebView android:id="#+id/webview1"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:visibility="invisible"
/>
</LinearLayout>
Code:
final Handler handler = new Handler();
...
final WebView mWebView1 = (WebView) findViewById(R.id.webview1);
mWebView1.getSettings().setJavaScriptEnabled(true);
mWebView1.getSettings().setPluginsEnabled(true);
mWebView1.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
mWebView1.setVisibility(View.VISIBLE);
}
}, 1000);
}
});
mWebView1.loadUrl("file:///android_asset/graph_01.swf");
There might be a better way though that would remove the need for a fixed delay...
It's been a while since I did anything with Flash but I seem to recall there is a way for the Flash control to use the browser's Javascript engine (a quick Google turns up the Flex Ajax Bridge which seems likely).
What you could do is, with the aforementioned bridge, use ActionScript to call a Javascript function which does an alert(). In your Java code you'd hook your mWebView1 up to a WebChromeClient which implements onJsAlert(). In that function you'd make the WebView visible.
I'm new at java and OpenGL.
I'm trying to get a camera preview screen with the ability to
display 3d objects simultaneously. Having gone through the samples at
the api demos, I thought combining the code for the the examples at
the api demo would suffice. But somehow its not working. The forces me
to shut down upon startup and the error is mentioned as null pointer
exception. Could someone share with me where did I go wrong and how to
proceed from there. How I did the combination for the code is as shown
below:
myoverview.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.opengl.GLSurfaceView
android:id="#+id/cubes"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<SurfaceView
android:id="#+id/camera"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</FrameLayout>
myoverview.java
import android.app.Activity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.Window;
public class MyOverView extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
// camera view as the background
SurfaceView cameraView = (SurfaceView) findViewById(R.id.camera);
cameraView = new CameraView(this);
// visual of both cubes
GLSurfaceView cubesView = (GLSurfaceView) findViewById(R.id.cubes);
cubesView = new GLSurfaceView(this);
cubesView.setRenderer(new CubeRenderer(false));
// set view
setContentView(R.layout.myoverview);
}
}
GLSurfaceView.java
import android.content.Context;
class GLSurfaceView extends android.opengl.GLSurfaceView {
public GLSurfaceView(Context context) {
super(context);
}
}
NOTE :
I didn't list the rest of the files as they are just copies of
the api demos. The cameraView refers to the camerapreview.java example
and the CubeRenderer refers to the CubeRenderer.java and Cube.java
example. Any help would be appreciated.
Sorry, didn't realize that the coding was out of place due to formatting mistakes.
the reason you are getting a null pointer exception when working with .xml is because ur actually creating new Views in your java code.. instead of using the ones from the .xml file to which you might have passed in properties(if u did pass in properties that is..).. the new View would obviously have a null value.. thus throwing a null pointer exception... for example --
cubesView = new GLSurfaceView(this);
is actually not needed in the code if you already created the View in the .xml file containing FrameLayout..
This is very simple actually...if you want to define your view in XML you just have to implement
Public GLSurfaceView(Context context, AttributeSet attrs) {
...
super(context, attrs);
}
instead of GLSurfaceView(Context context)
That's the one that gets called automatically when the view is initialized from the XML. I had the same problem and that's how it was fixed.
Found out how to solve it... via the java way... just use addContentView instead of using xml.... well at least its solved. :)
I actually did that here in this SO link which provides a complete implementation.