OK, I have a settings activity that is filled from a preferences.xml with addPreferencesFromResource(R.xml.preferences);, there is a dialog preference:
<com.android.maxr1998.cleanit.DialogPreference
android:title="#string/pref_dev"
android:key="dev"
android:dialogIcon="#drawable/alerts_and_states_warning"
android:dialogLayout="#layout/dev_dialog"
android:positiveButtonText="#android:string/yes"
android:negativeButtonText="#android:string/cancel"/>
Now, when I click Yes, I want another Activity to be launched...
This is my DialogPreference.class
package com.android.maxr1998.cleanit;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Region;
import android.provider.ContactsContract;
import android.util.AttributeSet;
public class DialogPreference extends android.preference.DialogPreference {
public DialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DialogPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public interface ClickListener {
public void onPositiveBtnClicked(...?);
}
}
What do I specifically have to put at "...?" ?
Solved it this way:
Used normal preference
Applied onclicklistener on Preference in Activity
Launch AlertDialog from it
Positive button click in alertdialog fires up activity
Write a Interface for the DialogPreference. Implement that in your activity. In positive click event callback.
class DialogPreference extends ... {
public interface ClickListener {
public void onPositiveBtnClicked(...);
}
public void setListener(ClickListener l) {
mClickListener = l;
}
#Override
onClick(DialogInterface dialog, int which) {
if(which == DialogInterface .BUTTON_POSITIVE) {
mClickListener.onPositiveBtnClicked(...)
}
}
}
Related
This question already has answers here:
Error inflating custom view
(5 answers)
Closed 2 years ago.
I am trying to do a photo editor app for my own learning and I am struggling to incorporate a View subclass in an XML file to better design the process.
Here is the XML code :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".home">
<com.example.digitaldesign.createObjectLayout
android:id="#+id/CreateObj"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Here is the View Class:
package com.example.digitaldesign;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.View;
public class createObjectLayout extends View {
Bitmap tshirt;
public createObjectLayout(Context context) {
super(context);
setBackgroundResource(R.drawable.wall);
tshirt = BitmapFactory.decodeResource(getResources(),R.drawable.tshirt);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect trect = new Rect();
trect.set(50,50,1050,1350 );
canvas.drawBitmap(tshirt,null,trect,null);
}
}
And here is the Activity:
```package com.example.digitaldesign;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
public class createObject extends AppCompatActivity {
createObjectLayout CreateObj;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CreateObj = new createObjectLayout(this);
LinearLayout layout1 =(LinearLayout) findViewById(R.id.CreateObj);
layout1.addView(CreateObj);
setContentView(R.layout.createobjectlyt);
}
}
And the error:
Caused by: android.view.InflateException: Binary XML file line #10: Binary
XML file line #10: Error inflating class
com.example.digitaldesign.createObjectLayout
Caused by: android.view.InflateException: Binary XML file line #10:
Error inflating class com.example.digitaldesign.createObjectLayout
Caused by: java.lang.NoSuchMethodException: <init> [class
android.content.Context, interface android.util.AttributeSet]
I tried to do everything like here : https://stackoverflow.com/questions/16504243/add-a-button-to-view#= , but i still get the error. Can you please tell me what am i doing wrong and how to fix it?
First of all you must get an error as you try to inflate widgets from XML layout before using setContentView()
So, modify your code to transfer setContentView() just after super.onCreate(savedInstanceState);
public class createObject extends AppCompatActivity {
createObjectLayout CreateObj;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.createobjectlyt);
CreateObj = new createObjectLayout(this);
...
}
}
The second thing you need to include all the constructors of your custom view
public class createObjectLayout extends View {
Bitmap tshirt;
public createObjectLayout(Context context) {
super(context);
setBackgroundResource(R.drawable.ic_launcher_background);
tshirt = BitmapFactory.decodeResource(getResources(), R.drawable.ic_menu_gallery);
}
public createObjectLayout(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
setBackgroundResource(R.drawable.ic_launcher_background);
tshirt = BitmapFactory.decodeResource(getResources(), R.drawable.ic_menu_gallery);
}
public createObjectLayout(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setBackgroundResource(R.drawable.ic_launcher_background);
tshirt = BitmapFactory.decodeResource(getResources(), R.drawable.ic_menu_gallery);
}
public createObjectLayout(Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setBackgroundResource(R.drawable.ic_launcher_background);
tshirt = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect trect = new Rect();
trect.set(50, 50, 1050, 1350);
canvas.drawBitmap(tshirt, trect, trect, new Paint());
}
}
Third, you will get ClassCastException as you inflate your custom view as a LinearLayout so change it to
createObjectLayout myView = findViewById(R.id.CreateObj);
Also as your custom view is not a ViewGroup, then you can't add views to it. So the below statement will raise exception
layout1.addView(CreateObj);
I encourage your to have a look at Android Custom Views
I can manage to generate a custom TextView with the help of stack overflow, now I am curious to concatenate a variable text with fixed string. I have done this but it doesn't help.
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
public class CustomTextViewTest extends android.support.v7.widget.AppCompatTextView {
public CustomTextViewTest(Context context) {
super(context);
}
public CustomTextViewTest(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomTextViewTest(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void setText(CharSequence text, BufferType type) {
super.setText(text, type);
// here set color according to text
if (text.toString().contains("Available")) {
this.setTextColor(getResources().getColor(R.color.green));
}
if(text.toString().contains("Not Available")){
this.setTextColor(getResources().getColor(R.color.red)); }
if(text.toString().startsWith("0")||text.toString().startsWith("1")||text.toString().startsWith("2")||
text.toString().startsWith("3")||text.toString().startsWith("4")||text.toString().startsWith("5")||
text.toString().startsWith("6")||text.toString().startsWith("7")||text.toString().startsWith("8")
||text.toString().startsWith("9")){
setText(text.toString()+" $"); //this line show something unexpected
}
}}
How to get rid of this?
If you want to show a numeric value and add a dollar sign at the end, first define a format string resource as follows:
<string name="amount">%1$s $</string>
and then later provide the numeric value as follows:
double amount = "100.00"
...
amountTextView.setText(context.getString(R.string.amount, amount));
I've been trying to get an app idea of mine to come to fruition for some time now. The idea is a weather app in which users can choose the content they want to see, and it is represented by cards (CardViews). For example, if they want to see only current weather and a 3 day forecast, they can enable that, and they'll see only those two cards in the MainActivity in a Google Now sort of fashion.
I've run into a few problems, and I need some help.
Firstly, how can I create the CardViews dynamically? My first attempt had the views completely defined in XML, but that didn't work very well because it doesn't seem very intuitive to hide/show them all the time. So I decided to extend the CardView class into things like a CurrentWeatherCardView and create the card completely programatically.
Here's the class I created from that. It's a child of the WeatherCardView class, which just extends CardView and doesn't do a whole lot else at this point.
package com.photonfighterlabs.particleweather.weathercardviews;
import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.photonfighterlabs.particleweather.MainActivity;
import com.photonfighterlabs.particleweather.weatherobjects.CurrentWeather;
import com.photonfighterlabs.particleweather.weatherobjects.Weather;
import java.io.File;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
public class CurrentWeatherCardView extends WeatherCardView {
private ViewGroup viewGroup;
private LinearLayout linearLayout_600, linearLayout_604, linearLayout_434;
private TextView cw_title, temp_text_view;
private ImageView icon_image_view;
private int is_day;
private CurrentWeather currentWeather;
public CurrentWeatherCardView(CurrentWeather currentWeather, Context context, Activity activity, ViewGroup viewGroup) {
super(context, activity);
this.currentWeather = currentWeather;
this.currentWeather.initialize(context, activity, MainActivity.API_KEY);
this.context = currentWeather.getContext();
this.viewGroup = viewGroup;
this.currentWeather.doOnResponse(() -> {
setupLayout();
setCw_title(currentWeather.getName(), currentWeather.getText());
Weather.setIconDrawable(currentWeather.getIcon(), icon_image_view, currentWeather.getIs_day());
setTemperature(currentWeather.getTemp_f());
});
}
public CurrentWeatherCardView(Context context) {
super(context);
}
public CurrentWeatherCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CurrentWeatherCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void setupLayout() {
LayoutParams cardParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, pixels(200));
cardParams.setMargins(
pixels(15),
pixels(15),
pixels(15),
0
);
super.setLayoutParams(cardParams);
super.setRadius(pixels(4));
super.setUseCompatPadding(true);
linearLayout_604 = new LinearLayout(context);
linearLayout_604.setBaselineAligned(false);
linearLayout_604.setOrientation(VERTICAL);
LayoutParams layout_170 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
linearLayout_604.setLayoutParams(layout_170);
this.addView(linearLayout_604);
linearLayout_600 = new LinearLayout(context);
linearLayout_600.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams layout_676 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, pixels(50));
linearLayout_600.setLayoutParams(layout_676);
linearLayout_604.addView(linearLayout_600);
cw_title = new TextView(context);
cw_title.setTypeface(Typeface.SANS_SERIF);
cw_title.setTextSize(pixels(5));
LayoutParams layout_914 = new LayoutParams(pixels(250), pixels(25));
layout_914.setMarginStart(pixels(10));
layout_914.topMargin = pixels(10);
cw_title.setLayoutParams(layout_914);
linearLayout_600.addView(cw_title);
icon_image_view = new ImageView(context);
LayoutParams layout_501 = new LayoutParams(pixels(75), pixels(40));
layout_501.setMarginStart(pixels(45));
layout_501.topMargin = pixels(10);
icon_image_view.setLayoutParams(layout_501);
linearLayout_600.addView(icon_image_view);
linearLayout_434 = new LinearLayout(context);
linearLayout_434.setOrientation(HORIZONTAL);
LayoutParams layout_204 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
linearLayout_434.setLayoutParams(layout_204);
temp_text_view = new TextView(context);
temp_text_view.setTextAlignment(TEXT_ALIGNMENT_TEXT_START);
temp_text_view.setTextSize(pixels(8));
LayoutParams layout_725 = new LayoutParams(pixels(100), pixels(100));
layout_725.setMarginStart(pixels(25));
layout_725.topMargin = pixels(10);
temp_text_view.setLayoutParams(layout_725);
linearLayout_434.addView(temp_text_view);
linearLayout_604.addView(linearLayout_434);
viewGroup.addView(this);
}
private void setCw_title(String title, String condition) {
cw_title.setText(title + " - " + condition);
}
private void setTemperature(double temp) {
temp_text_view.setText(String.valueOf((int) temp) + '\u00b0');
}
}
It's messy, but is there a better way? Doing it this way allows me to create this CardView by just instantiating the class, but I'm running into issues with figuring out what kind of view I should put these in. RecyclerView doesn't really seem like the right choice because as far as I can tell it's creates cards from a dataset. In my case, the CurrentWeatherCardView will always be the same.
That leads me to my next question. In what way can I have a scrollable, side-swipeable set of cards? RecyclerView? ListView? I'm pretty lost, and any guidance would help.
CardView is extended from FrameLayout, so you can just use a xml to design what your card looks like, and use findViewById in this CurrentWeatherCardView. For example:
public CurrentWeatherCardView(Context context) {
super(context);
init();
}
public CurrentWeatherCardView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CurrentWeatherCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
LayoutInflater.from(this).inflate(R.layout.xxx, this, true);
xxx = findViewById(R.id.xxxxx);
...
xxx.setText(xxxx)
// if you want to change visibility, just call:
setVisibility(View.GONE/View.VISIBILE);
}
This question already has answers here:
How to set a particular font for a button text in android?
(9 answers)
Closed 5 years ago.
I created an android studio default navgation view and i put two buttons in nav_header_main.xml (see the picture below)
now i want to set a custom font for the button.
i tried this in MainActivity.java :
Typeface font = Typeface.createFromAsset(getAssets(), "fonts/myfont.ttf");
Button b = (Button) findViewById(R.id.login_btn);
b.setTypeface(font);
but it didn't work!!
how can i do this?
Screenshot
You have to write a custom class extending from Button.
Here is an example:
package com.example.test;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.TextView;
public class CustomFontButton extends Button {
public CustomFontButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CustomFontButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomFontButton(Context context) {
super(context);
init();
}
private void init() {
Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/myfont.ttf");
setTypeface(font);
}
}
Use it from XML:
<com.example.test.CustomFontButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button Text" />
My problem is really straight forward. I can't seem to figure out why it's throwing an error of this kind (to add, I've never really used Java but have to for a simple android app now).
In my activity class I declare:
private MyWebView web;
Inside the 'onCreate' method I do this:
try {
web = (MyWebView)findViewById(R.id.webview);
}
catch(Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
}
The class 'MyWebView' looks like this:
import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebView;
public class MyWebView extends WebView {
public MyWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
#Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
}
}
This throws an a 'ClassCastException' with detailMessage = "android.webkit.WebView.
I'd really appreciate some help.
Thanks
the name in the layout was the one thing which was wrong. After I tried it again it errored again, but this time it triggered a 'MethodNotFoundException'. It seems like you have to implement this constrcutor
MyWebView(Context context, AttributeSet attrs)
instead of this one
MyWebView(Context context, AttributeSet attrs, int defStyle)
like eclipse suggests...
you have to name your custom WebView like this in your layout:
<yourpackagename.MyWebView
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
yourpackagename: is the name of the package in wich you decalred your MyWebView Class