Canot resolve android.support.v7.internal.widget.TintImageView - android

I tried to set compileSdkVersion in my project to 23 and also updated the below libraries:
com.android.support:appcompat-v7:23.1.1
com.android.support:recyclerview-v7:23.1.1
com.android.support:cardview-v7:23.1.1
Since then I am getting error at importing android.support.v7.internal.widget.TintImageView
Can anyone please tell me why is it so? Any change in the package of TintImageView? Kindly help.
I am using Studio Preview 2.0

It happens because the class
android.support.v7.internal.widget.TintImageView
doesn't exist in the appcompat v 23.x.x.
In general don't use the classes in the internal package.
You can check the source in the folder androidsdk\extras\android\m2repository\com\android\support\appcompat-v7\.
You should switch to the AppCompatImageView.
A ImageView which supports compatible features on older version of the platform, including:
Allows dynamic tint of it background via the background tint methods in ViewCompat.
Allows setting of the background tint using backgroundTint and backgroundTintMode.
This will automatically be used when you use ImageView in your layouts. You should only need to manually use this class when writing custom views.

Use this for tinting an ImageView:
<android.support.v7.widget.AppCompatImageView
android:id="#id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/my_image"
android:tint="#636363"
/>

Related

Android Widget use app:srcCompat for ImageView

I have Widget with ImageView. When i use android:src for set image for ImageView everything all right, but when i use app:srcCompat image don't show.
Is there a way to use app:srcCompat in Android Widget?
It's set in my project:
xmlns:app="http://schemas.android.com/apk/res-auto"
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
minSdkVersion 24
targetSdkVersion 29
I don't think this is possible. ImageView doesn't actually have a app:srcCompat attribute (see here).
The reason why you're normally able to use it, is that ImageView is automatically replaced by AppCompatImageView when you use the appcompat library. However this doesn't work with widgets since they are based on RemoteViews. As you have seen, with RemoteViews you can only use ImageView and not AppCompatImageView. Even if you add the appcompat library to your own app, the problem is that the RemoteViews object for your widget will be handed to the process of the app that will display the widget (typically the launcher), where we can't assume appcompat to be available.
Are you trying to use appcompat because of problems with your vector assets? If you describe the problem you're having with them maybe we can find a way to make it work with regular ImageViews.
Try <androidx.appcompat.widget.AppCompatImageView> instead if <ImageView>

What would be a best practice to draw a custom TextView path in RecyclerView?

I need to draw categories path like in the picture bellow, problem is item shape
what would be a best practice to achieve it?
I can think about few options like:
Extending TextView and changing it shape
Adding vector drawable background
Adding xml drawable background
Any ideas?
Following are my understanding:
Extending TextView and changing it shape
This will load TextView at runtime and so will not be memory-efficient.
Adding vector drawable background
This is a good practice. But the native Vector drawable support is from API level 21. To support lower api devices you will need to add vectorDrawables.useSupportLibrary = true and modify build.gradle file as:
// Gradle Plugin 2.0+
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Android Studio 1.4+ will generate pngs at build time.
Adding xml drawable background
This will support all the versions and kind of the easiest solution.
My suggestion will be to use Vectordrawables. This will give the
best support with different Android versions.

Use SVG in CompoundDrawable with SDK<21

I was using SVG's in my Android application as src of my ImageView, using appSrc attribute in order to give compatibility backwards (SDK<21).
But now I have tried to use them in my TextView Compound Drawables (drawableXXX attributes) and I get multiple errors when I use a device with KitKat (The same errores that I had when I used android:src instead of app:srcCompat).
Caused by: android.view.InflateException: Binary XML file line #261: Error inflating class
Is there anyone who know a way to use them in Compound Drawables?
as of now you cannot add a VectorDrawable from xml attributes, that functionality is only limited to app:srcCompat more on this in the android developers blog post
However you may do it programmatically using VectorDrawableCompat.create(Resources, int, Theme) and then add it as a compound drawable to the TextView using TextView#setCompoundDrawables
see :
developer.android.com/reference/android/support/graphics/drawable/VectorDrawableCompat.html
developer.android.com/reference/android/widget/TextView.html
I had the same issue and i found only two options:
1) set your drawable programmatically or create a custom view
2) remove "vectorDrawables.useSupportLibrary = true" from your build.gradle
This will cause Android Studio to generate PNGs at compile time for apps with a minSdkVersion less than API 21 while using your vectors on API 21+ devices, allowing you to keep the same code at the cost of additional APK size.
As is described in this article, you can create a little hack for this issue. Just create layer-list drawable file(ic_working_image.xml) like this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_your_image_name"/>
</layer-list>
And then just use the new drawable on TextView as before with drawableXXX attributes.

Using android vector Drawables on pre Lollipop crash

I'm using vector drawables in android prior to Lollipop and these are of some of my libraries and tool versions:
Android Studio : 2.0
Android Gradle Plugin : 2.0.0
Build Tools : 23.0.2
Android Support Library : 23.3.0
I added this property in my app level Build.Gradle
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
It is also worth mentioning that I use an extra drawable such as LayerDrawable(layer_list) as stated in Android official Blog (link here) for setting drawables for vector drawables outside of app:srcCompat
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/search"/>
</level-list>
You’ll find directly referencing vector drawables outside of
app:srcCompat will fail prior to Lollipop. However, AppCompat does
support loading vector drawables when they are referenced in another
drawable container such as a StateListDrawable, InsetDrawable,
LayerDrawable, LevelListDrawable, and RotateDrawable. By using this
indirection, you can use vector drawables in cases such as TextView’s
android:drawableLeft attribute, which wouldn’t normally be able to
support vector drawables.
When I'm using app:srcCompat everything works fine, but when I use:
android:background
android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom
on ImageView, ImageButton, TextView or EditText prior to Lollipop, it throws an expection:
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9
LATEST UPDATE - Jun/2019
Support Library has changed a bit since the original answer. Now, even the Android plugin for Gradle is able to automatically generate the PNG at build time. So, below are two new approaches that should work these days. You can find more info here:
PNG Generation
Gradle can automatically create PNG images from your assets at build time. However, in this approach, not all xml elements are supported. This solution is convenient because you don't need to change anything in your code or in your build.gradle. Just make sure you are using Android Plugin 1.5.0 or higher and Android Studio 2.2 or higher.
I'm using this solution in my app and works fine. No additional build.gradle flag necessary. No hacks is necessary. If you go to /build/generated/res/pngs/... you can see all generated PNGs.
So, if you have some simple icon (since not all xml elements are supported), this solution may work for you. Just update your Android Studio and your Android plugin for Gradle.
Support Library
Probably, this is the solution that will work for you. If you came here, it means your Android Studio is not generating the PNGs automatically. So, your app is crashing.
Or maybe, you don't want Android Studio to generate any PNG at all.
Differently from that "Auto-PNG generation" which supports a subset of XML element, this solution, supports all xml tags. So, you have full support to your vector drawable.
You must first, update your build.gradle to support it:
android {
defaultConfig {
// This flag will also prevents Android Studio from generating PNGs automatically
vectorDrawables.useSupportLibrary = true
}
}
dependencies {
// Use this for Support Library
implementation 'com.android.support:appcompat-v7:23.2.0' // OR HIGHER
// Use this for AndroidX
implementation 'androidx.appcompat:appcompat:1.1.0' // OR HIGHER
}
And then, use app:srcCompat instead of android:src while loading VectorDrawables. Don't forget this.
For TextView, if you are using the androidx version of the Support Library, you can use app:drawableLeftCompat (or right, top, bottom) instead of app:drawableLeft
In case of CheckBox/RadioButton, use app:buttonCompat instead of android:button.
If you are not using the androidx version of the Support Library and your minSdkVersion is 17 or higher or using a button, you may try to set programmatically via
Drawable icon = AppCompatResources.getDrawable(context, <drawable_id>);
textView.setCompoundDrawablesWithIntrinsicBounds(<leftIcon>,<topIcon>,<rightIcon>,<bottomIcon>);
UPDATE - Jul/2016
They re-enabled that VectorDrawable in
Android Support Library 23.4.0
For AppCompat users, we’ve added an opt-in API to re-enable support Vector Drawables from resources (the behavior found in 23.2) via AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) - keep in mind that this still can cause issues with memory usage and problems updating Configuration instances, hence why it is disabled by default.
Maybe, build.gradle setting is now obsolete and you just need to enable it in proper activities (however, need to test).
Now, to enable it, you must do:
public class MainActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
...
}
Original Answer - Apr/2016
I think this is happening because Support Vector was disabled in the latest library version: 23.3.0
According to this POST:
For AppCompat users, we’ve decided to remove the functionality which let you use vector drawables from resources on pre-Lollipop devices due to issues found in the implementation in version 23.2.0/23.2.1 (ISSUE 205236). Using app:srcCompat and setImageResource() continues to work.
If you visit issue ISSUE 205236, it seems that they will enable in the future but the memory issue will not be fixed soon:
In the next release I've added an opt-in API where you can re-enable the VectorDrawable support which was removed. It comes with the same caveats as before though (memory usage and problems with Configuration updating).
I had a similar issue. So, in my case, I reverted all icons which use vector drawable from resource to PNG images again (since the memory issue will keep happening even after they provide an option to enable it again).
I'm not sure if this is the best option, but it fixes all the crashes in my opinion.
I had the same problem.
But doing a lot of R&D I got the answer.
For Imageview and ImageButton use,app:srcCompat="#drawable/...."
and for other views like Button, Textview, instead of using "drawableLeft/right..." in the XML, specify drawables programmitically as :
button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null);
And use "AppCompatResources" to get the drawable.
To elaborate on the other very good answers, here is a diagram that can help you. It is valid if you have Support Library from 23.4.0 to at least 25.1.0.
The answer from Guillherme P is pretty awesome. Just to make a small improvement, you don't need to add that line in every activity, if you added it once in the Application class it will work as well.
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
REMEMBER: You still need to have enabled the use of the support library in gradle:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Also, make sure you are using a support library version greater than v23.4, when Google added back the support for Drawable Containers for VectorDrawables (release note)
Update
And for code changes:
Make sure to update to app:srcCompat every place that accepts the android:src attribute (the IDE will warn you if it's invalid like for the <bitmap> tag).
For drawableLeft, drawableStart, drawableRight, drawableEnd attributes used in TextView and similar views, you will have to set them programmatically for now. An example of setting drawableStart:
Drawable drawable = AppCompatResources.getDrawable(
getContext(),
R.drawable.your_vector_drawable);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
}
I had the same problem. And fix it by removing
vectorDrawables.useSupportLibrary = true
My target version is 25 and support library is
compile 'com.android.support:appcompat-v7:25.3.1'
VectorDrawables on pre-lollipop should work fine without using
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
If you want to use VectorDrawables inside ImageViews, you can use the attribute srcCompat and it will work, but inside Buttons or TextViews it won't, so you need to wrap the Drawable into an InsetDrawable or a LayerDrawable. There is another trick I discovered, if you are using data binding, you could do this:
android:drawableLeft="#{#drawable/vector_ic_access_time_24px}"
android:drawableStart="#{#drawable/vector_ic_access_time_24px}"
That will magically work, I haven't investigated what's happening behind the scenes, but I guess the TextView is using the getDrawable method from the AppCompatResources or similar.
Lot of R & d, finally getting this solution for crashes on pre-lollipop devices.
For Imageview
use app:srcCompat instead of android:src
For TextView/EditText
Remove drawableleft,drawableright.... and set from drawable java code.
txtview.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(EventDetailSinglePage.this,
R.drawable.ic_done_black_24_n), null, null, null);
For Build.gradle
vectorDrawables.useSupportLibrary = true
Easiest way use :
app:drawableRightCompat ="#drawable/ic_mobilelogin"
app:drawableEndCompat="#drawable/ic_mobilelogin"
app:srcCompat="#drawable/ic_mobile"
and... just use app:**Compatfor compatability.
Also add support on build.gradle (module)
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
For anyone who upgrade to android gradle 3.0 and above, there is no need to use AppCompatDelegate.setCompatVectorFromResourcesEnabled(true), or set vectorDrawables.useSupportLibrary = true (add this will cause problem) and use app:srcCompat, it just works.
Take me two days to figure this out, and have not find any related docs in google's docs...
After using the below code.
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}}
still, vector images issue exists for below attributes are
DrawableEnd,
DrawableStart,
DrawableTop,
DrawableBottom,
Background
In this case, please follow as below, Instead of referencing vector image directly use selector tag as an intermediate drawable file.
Example:
ic_warranty_icon.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportWidth="17"
android:viewportHeight="24">
<path
android:fillColor="#fff"
android:pathData="M10.927,15.589l-1.549,0.355a7.47,7.47 0,0 1,-0.878 0.056c-4.136,0 -7.5,-3.364 -7.5,-7.5s3.364,-7.5 7.5,-7.5 7.5,3.364 7.5,7.5c0,3.286 -2.126,6.078 -5.073,7.089zM8.5,2a6.508,6.508 0,0 0,-6.5 6.5c0,3.583 2.917,6.5 6.5,6.5s6.5,-2.917 6.5,-6.5 -2.917,-6.5 -6.5,-6.5z" />
safe_ic_warranty_icon.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_warranty_icon" />
</selector>
Your TextView/Layout.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="#drawable/ic_warranty_icon"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_warranty_icon"
/>
I am using VectorDrawables on Pre-lollipop devices and this is how I do it :-
Step 1:
Put this in your app level gradle.
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Step 2:
Put this in your Application class and don't forget to register your Application class in the manifest file.
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
}
Step 3:
Get VectorDrawables using,
imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable));
We tried 3 things
vectorDrawables.useSupportLibrary = true
Setting setCompatVectorFromResourcesEnabled in Application class
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
And use app:srcCompat
But even after that it was failing with
Resources$NotFoundException: File res/drawable/$my_icon__0.xml from color state list resource ID #0x7f080008
then we figured out that our SVG had a Gradient tag.
Converting the gradient tag to individual paths for below API <= 23 and using the same SVG API >= 24 worked.
Got help from this answer https://stackoverflow.com/a/47783962/2171513
I was struggling with this for hours.
I tried everything these answers told me to, but my app didn't stop crashing. I deleted this line: app:srcCompat="#drawable/keyboard" and my app stopped crashing. and then when I added this same thing back, it started crashing again. So I decided to open that file and I saw an error at the first line saying
"The drawable 'Keyboard' has no declaration in the base drawable
folder; this can lead to crashes.
I right-clicked the file and clicked "Show in explorer" and it was not in the drawable folder but in the drawable-v24 directory. So I copied it and pasted to the drawable directory and finally got rid of crashes.
Simply overlap vector drawable to state-list then problem will be solved
For example you have back arrow vector image:
ic_back_arrow.xml
yes, you should overlap it to layer list xml (ic_back_arrow_vector_vector.xml):
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_back_arrow"/>
</layer-list>
Because logic:
vectorDrawables.useSupportLibrary = true
and
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
will not help you on the some China devices and older samsung devices. If you do not overlap them, it will fail.
In my case, I was using a TabLayout, which I configured as it :
TabLayoutMediator(tabLayout!!, viewPager!!) { tab, position ->
if (position == 0)
tab.icon = ResourcesCompat.getDrawable(resources, R.drawable.ic_list, theme)
else
tab.icon = ResourcesCompat.getDrawable(resources, R.drawable.ic_building_map, theme)
}.attach()
The app was crashing at line tab.icon = ...
I change these to tab.setIcon(R.drawable.my_vector_asset), as it :
TabLayoutMediator(tabLayout!!, viewPager!!) { tab, position ->
if (position == 0)
tab.setIcon(R.drawable.ic_list)
else
tab.setIcon(R.drawable.ic_building_map)
}.attach()
And it worked !
Guilherme P's suggestion was not working for me. I went ahead and made the decision to use png's where I need to do things outside of app:srcCompat i.e. drawableLeft, drawableRight, etc. This was a pretty easy change to make, and doesn't have the potential memory issues AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
introduces.
An alternative to Benny's answer is to create an Activity superclass:
public abstract class VectorDrawableActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
//...
}
Now extend VectorDrawableActivity instead of AppCompatActivity.

Using android default buttons

I found these website http://androiddrawables.com/Buttons.html where you can check the differences between Android buttons .
How can I use them? If I type R.drawables.btn_star_big_on_pressed the editor says it couldn't find the resource.
How can I use those default Android images ?
I am using 4.0.
The only way I know how to use them is:
<ImageView
android:id="#+id/imageView"
android:layout_width="48px"
android:layout_height="48px"
android:src="#android:drawable/btn_radio" />
to check available buttons type first letter after drawable/.
Then navigate to the button and you will see the selectors.
You can do something like this,
android.R.drawable.btn_star
Default resources for UI components depend on the device and platform version that your app is running on. For your button's to use them you would want to simply not declare a background resource.
My advice is that you will go to the Android SDK folder/platforms/android-##/data/res/drawable-dpi and copy the icons from there into your own res folder.

Categories

Resources