Android: define which attributes a custom view uses for content assist - android-layout

I've got some custom views and custom defined attributes. I'd like to define which attributes my views use so that eclipse can use that for content-assist.
For example, I've got a custom xml attribute declared like so in my res/values folder:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TagAttrs">
<attr name="spColor" format="color" />
</declare-styleable>
</resources>
And my layout file uses a custom view with the custom attribute:
<?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/com.twp"
...
>
<com.twp.TestView
android:id="#+id/testView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:spColor="#FF00FF" >
...
</com.twp.TestView>
</LinearLayout>
If I use the android: prefix, eclipse presents all the options it would for a LinearLayout (from which TestView derives), but if I use the app: prefix, it shows in red at the bottom that "Element com.twp.TestView not available". Also, if I try content-assist inside of spColor, it says "Content Assist not available at the current location." I would think since I defined the "app" namespace, it would be able to find my stylable declaration and at least know that spColor is a color.
So it this just a limitation of eclipse, or can I explicitly define a view's custom attributes?

I believe the value for the name attribute in declare-styleable needs to match the unqualified name of the associated class or the unqualified name of a superclass of the associated class. So if the direct superclass of TestView is LinearLayout, then the value of the name attribute in the associated declare-styleable should be TestView, not TagAttrs.

Related

how to make action from included graph?

I can make action from nested graph to any destination, but apprently I can't make action from included other file.
i thought included graph and nested graph is almost same.
how can I make action from included graph?
You can create a global action in the main navigation graph
Like:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_graph"
app:startDestination="#id/x">
<fragment
android:id="#+id/x"
android:name="x"/>
<include app:graph="#navigation/x" />
<fragment
android:id="#+id/firstFragment"
android:name="x"/>
<action
android:id="#+id/action_global_to_firstFragment"
app:destination="#id/firstFragment" />
</navigation>
And then call it with the id:
navController.navigate(R.id.action_global_to_firstFragment)
The navController must be the defined in the ActivityContainer, if it generate a destination error, maybe you aren't using the main navController

how to extend ImageView class in kotlin?

I found strange behavior when extending ImageView in kotlin.
I have following layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<AlphaImage
android:id="#+id/imageView2"
android:layout_width="320dp"
android:layout_height="50dp"
app:srcCompat="#drawable/blitz_1st_place" />
</FrameLayout>
AlphaImage class:
class AlphaImage(context: Context,attrs:AttributeSet?=null):ImageView(context,attrs) {
}
The layout preview in android studio shows image as 100% transparent as well as in runtime.There are no errors in the layout editor.What interesting is if I change AlphaImage to ImageView image starts to display its content as expected.Why is this happening?How do I extend ImageView?
The issue here is the app:srcCompat attribute. That is a support/androidx library attribute for the AppCompatImageView class. The framework ImageView will just ignore it.
The reason this works when you use an <ImageView> tag instead is because the support/androidx LayoutInflater that AppCompatActivity uses will automatically substitute an AppCompatImageView for any <ImageView> tag it finds. The AppCompatImageView will then see that app:srcCompat attribute, and handle its value appropriately.
If you'd like your custom class to handle that attribute automatically, simply extend AppCompatImageView instead of ImageView.

unable to add a fragment tag inside a relative layout

I want to add a tag inside a RelativeLayout of an Activity. But i am getting rendering errors.
Any help on how to solve?
Edit: Adding the stacktrace of the crash
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.chandranichatterjee.mapapp/com.example.chandranichatterjee.myapplicationloc.MapsActivityNew}: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2583)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1499)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5767)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
Caused by: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class fragment
at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:412)
at android.app.Activity.setContentView(Activity.java:2204)
at com.example.chandranichatterjee.myapplicationloc.MapsActivityNew.onCreate(MapsActivityNew.java:24)
at android.app.Activity.performCreate(Activity.java:6322)}
As suggested by #Nazariy Moshenskiy , I needed to add android:name attribute to the <fragment> tag.
This is how my layout looked like(in case someone encounters the same problem in future).
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraZoom="2"
tools:context=".MapsActivityNew" />
I think you need to add android:name="com.example.myapp.YourFragmentHere" inside your fragment to define a Fragment class if you are going to use <fragment> tag.
As your error message says:
A <fragment> tag allows a layout file to dynamically include different layouts at runtime. At layout editing time the specific layout to be used is not known. You can choose which layout you would like previewed while editing the layout.
It doesn't know what the Fragment should show, but it can be ignored, since the result in the end does know it. You can't just have such a general preview.
Edit:
Most common mistakes from experience with inflating a fragment are:
using:
public class MainActivity extends Activity {
instead of:
public class MainActivity extends FragmentActivity {
and having meta-data tag outside the application in the manifest file.
You have to add android:name="com.example.YourFragmentHere inside your fragment tag to define a Fragment class. like this
<fragment
android:id="#+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.YourFragmentHere"
/>

i cant add button to linear layout

I have a listActivity that displays via an adapter an xml feed fetched from the web, adn the layout file activity_list_feed.xml :
`<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
android:transcriptMode="normal"
/>`
In the graphic editor i cannot drag a button into this layout, and when i try to hardcode as per this file :
`<?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" >
<Button
android:id="#+id/addBtn"
android:text="Add New Item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="addItems"/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
android:transcriptMode="normal"
/>
</LinearLayout>`
i get a compile error message :
java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.TextView
How can i add a button on top of the list because i want to refresh the pull.thank you.
The code that you provided actually works in its current state in Android Studio:
Make sure that in your java code, you are referencing the correct item. Make sure that you're setting the overall layout to be that layout, and THEN doing findViewById(R.layout.addBtn).
Also, try changing the Android Version in your IDE to 22 (as I have it set in the top right corner of the picture). That may solve your error.
I managed to add the button in the editor and this without setting to API 22 as per your picture. However the program didn't compile still.
The message error "ArrayAdapter requires the resource ID to be a TextView" meant i didn't provide the right argument to the adapter.
According to this answer :
"ArrayAdapter requires the resource ID to be a TextView" xml problems
it appears that the choice of the constructor is important, since i wanted to add a button in the view, i must use the constructor with 4 arguments (the additional argument being the id of the view):
http://developer.android.com/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context,int,int,java.util.List)
Using this constructor solved the problem.

Problems with relative layout: No resource found that matches the given name

I'm going crazy with this problem...
I would like to do something like this:
This is my SIMPLY code into the xml layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:p1="http://schemas.android.com/apk/res/android"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="match_parent"
p1:id="#+id/relativeLayout1">
<WebView
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:id="#+id/webView1"
p1:layout_alignParentTop="true"
p1:layout_above="#id/textView1" />
<TextView
p1:text="Medium Text"
p1:textAppearance="?android:attr/textAppearanceMedium"
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:id="#+id/textView1"
p1:layout_alignParentBottom="true" />
</RelativeLayout>
but the error that I receive is this:
Error: No resource found that matches the given name (at 'layout_above' with value '#id/textView1').
That is so strange for me.... because I have specified textView1!!!!
Some idea?!?
The TextView with the id textView1 is parsed after the WebView that is referencing it. Using the #id/* syntax specifies that the parser is resolving an existing id. In this case it will fail as your TextView hasn't been parsed yet.
Use layout_above=#+id/textView1 instead to predeclare the id for your TextView.

Resources