I'm trying to make a kind of tick-tac-toe android app (though with a 4x4 grid). I decided using buttons to depict each grid square and wanted to use data bindings to bind the text on the buttons to data from a String[][] array that would represent the grid internally. I tried doing something similar to what was presented here http://www.vogella.com/tutorials/AndroidDatabinding/article.html so I created this class:
public class ModelJoc extends BaseObservable{
private String[][] tabla_joc;
public ModelJoc() {
for (String[] line : tabla_joc)
for (String element : line)
element = "";
tabla_joc[0][0] = "M";
tabla_joc[0][1] = "W";
}
And then added the data binding to the activity_main.xml:
<android.support.constraint.ConstraintLayout 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="com.example.tgeorge.temajoc.MainActivity">
<data>
<variable
name="state"
type="com.example.tgeorge.temajoc.ModelJoc"/>
</data>
And then tried to set the text of a button to a value from the array:
<Button
android:id="#+id/button1"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="#={state.getBlockState()[0][0]}"/>
But it gives me these errors: "Element data is not allowed here" as well as "Attribute is missing the android: prefix". I can't tell what I'm doing wrong from the example in the tutorial so the question is where exactly should I be putting these?
I think I see the problem now. You must outline your layout with a <layout> tag:
<layout 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"
tools:context="com.example.tgeorge.temajoc.MainActivity">
<data>
<variable
name="state"
type="com.example.tgeorge.temajoc.ModelJoc"/>
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- ... -->
<Button
android:id="#+id/button1"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="#{state.getBlockState()[0][0]}"/>
If you don't do that, android data binding won't recognize it as a data bound layout file.
Related
I am trying to change between images using fade in/out and I am having a difficult time.
This is what I have for the code
public void fade(View view)
{
ImageView loveLive = findViewById(R.id.lovelive);
ImageView rikoCheer = findViewById(R.id.rikoCheer);
loveLive.animate().alpha(0f).setDuration(2000);
rikoCheer.animate().alpha(1f).setDuration(2000);
}
public void fade2(View view)
{
ImageView rikoCheer = findViewById(R.id.rikoCheer);
ImageView loveLive = findViewById(R.id.lovelive);
rikoCheer.animate().alpha(0f).setDuration(2000);
loveLive.animate().alpha(1f).setDuration(2000);
}
Here is my xml file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">
<ImageView
android:id="#+id/lovelive"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="fade"
app:srcCompat="#drawable/lovelive"
tools:layout_editor_absoluteX="50dp"
tools:layout_editor_absoluteY="-69dp" />
<ImageView
android:id="#+id/rikoCheer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:onClick="fade"
app:srcCompat="#drawable/rikocheer"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
so my goal for this is to fade in and fade out between images
What's going wrong exactly? If nothing's showing up it might be that you don't have any layout constraints set up for your images (the tools: stuff only affects the layout editor, like fake data for testing, it doesn't apply when you run the app)
There's something called a TransitionDrawable you might want to use, you'd basically create a new Drawable XML file and put this in it
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/lovelive" />
<item android:drawable="#drawable/rikocheer" />
</transition>
and then you can just use that in an ImageView or whatever.
In your code you'd go
myImage = (TransitionDrawable) findViewById<ImageView>(R.id.thatImageView).getDrawable()
and then you can call myImage.startTransition(duration) to go from image 1 to image 2, or myImage.reverseTransition(duration) to go back to the first image. You can switch immediately with resetTransition() for image 1 or startTransition(0) to go straight to image 2
You also might want to use setCrossfadeEnabled() on the TransitionDrawable - when it's false the first image is always opaque, so the second is drawn on top of it like an overlay. If it's set to true you get one fading out while the other fades in - depends what you want!
I'd like my Spinner dropdown items to fill the entire screen width even tho my 'title' does not. Problem is the dropdown menu width seems to be limited the Spinner's title width.
My goal is to make it fill the entire screen width, with no spacing left or right, right below the action bar. A similar one to what I'm trying to do would be Instagram's menu to change profile.
I looked to similar questions but didn't find a solution that worked here. Also tried to create a custom adapter and making sure its views had match_parent attribute on their width. But didn't work either.
main.java (only relevant part of the code for legibility)
mMyListsSpinner = (Spinner) findViewById(R.id.spinner_mylists);
ArrayAdapter<String> snipperAdapter = new ArrayAdapter<String>(
FamilistActivity.this, R.layout.layout_spinner_title, dummyLists);
snipperAdapter.setDropDownViewResource(R.layout.layout_spinner_dropdown);
mMyListsSpinner.setAdapter(snipperAdapter);
mMyListsSpinner.setOnItemSelectedListener(this);
layout_spinner_title.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#color/color_white_bright"
android:maxLines="1"
style="#style/OverflowMenu"
android:text="this is my list"/>
layout_spinner_dropdown.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_spinner_dropdown"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_actionbar_height"
android:maxLines="1"
android:textSize="18sp"
android:textColor="#color/color_green_dark"
android:background="#color/color_white_bright"/>
styles.xml (only the relevant part)
<style name="OverflowMenu" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="overlapAnchor">false</item>
<item name="android:dropDownVerticalOffset">16dp</item>
<item name="android:dropDownHorizontalOffset">-15dp</item>
</style>
my toolbar:
toolbar.xml
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bar_appbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_actionbar_height"
app:layout_collapseMode="pin"
android:background="#color/color_green_bright">
<Spinner
android:id="#+id/spinner_mylists"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:spinnerMode="dropdown"
android:dropDownWidth="match_parent"
style="#style/OverflowMenu"/>
By looking into AppCompatSpinner.java and running the debugger I saw in this line in computeContentWidth()
else if (mDropDownWidth == MATCH_PARENT) {
setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight);
}
that SpinnerPaddingRight has a value that is not 0. I solved it by setting
android:paddingEnd="0dp"
in the Spinner view.
I have made a BindingConversion from boolean to visibility, however Android can't find it, but only when I use it in an include tag. It works at other elements like FrameLyout.
In my abstract ViewModel:
#BindingConversion
public static int convertBooleanToVisibility(boolean visible) {
return visible ? View.VISIBLE : View.GONE;
}
Then in my xml (TestViewModel inherits from ViewModel):
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="oliveradam.testapp.viewmodels.TestViewModel"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
app:theme="#style/toolbarStyleMusicView"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize">
</android.support.v7.widget.Toolbar>
<include
android:visibility="#{viewModel.isVisible}"
layout="#layout/layout_test"
app:viewModel="#{viewModel}" />
</LinearLayout>
</layout>
Error:(139, 29) error: cannot find symbol method setVisibility(boolean)
I'm working on Android Studio 2.2 RC.
I don't know why this is not working, but I think its the layout tag in include. You can't use these tags for databinding. So I deleted the includes, used a viewstub and changed the layouts programmatically.
I have a layout which I want to be scrollable when content is overflowing the screen.
I have the following layout xml set up.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="#+id/ScrlView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:isScrollContainer="false"
android:id="#+id/home_root"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/backrepeat">
<!-- Include Header -->
<include layout="#layout/main_header"/>
<!-- Include dashboard -->
<include layout="#layout/dashboard"/>
</LinearLayout>
</ScrollView>
A dashboard is a collection of icons serving as a menu. Example: click me
Unfortunately, the second include (dashboard) shows 'broken' now. See screen:
Click here
As you can see it doesn't look like it's suposed to. When I delete the scrollview, everything is fine.
What I want is for my dashboard to still look good, but be scrollable if needed.
I tried several setups but all give the same result. What am I doing wrong?
Any help would be appreciated :)
Remove the android:isScrollContainer="false", and add android:fillViewport="true" to scrollView
How can I assign each view an automatic margin?
Example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button ... />
<Button ... />
<Button ... />
<Button ... />
</LinearLayout>
I want each of these buttons to have the same amount of space between them.
Now I could just put a layout_marginTop and a layout_marginBottom attribute in each of the tags and set their values to what I want them to be, but isn't there an easier way to do this?
Can I somehow automatically set each view's margin in my LinearLayout to a specific value without having to type it in every tag?
You can use the layout weight of the object
Set each of the buttons to have an equal layout weight and then set each of their heights to match_parent
That should resolve your issue.