Visibility binding fails - visibility

I try to use the Visibility plugin with the FieldBinding plugin with no luck.
Model side:
/// <summary>
/// Gets or sets the birthdate.
/// </summary>
/// <value>
/// The birthdate.
/// </value>
public DateTime? Birthdate { get; set; }
ViewModel side:
public class DisplayUserViewModel : BaseUserViewModel
{
/// <summary>
/// The user
/// </summary>
public readonly INC<User> User = new NC<User>();
}
View side, first try:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="#dimen/ListIconTwoLineTileHeight"
android:paddingRight="#dimen/ListIconTwoLineTextMarginRight"
local:MvxBind="Visibility User.Birthdate, Converter=Visibility">
Second try:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="#dimen/ListIconTwoLineTileHeight"
android:paddingRight="#dimen/ListIconTwoLineTextMarginRight"
local:MvxBind="Visibility Visibility(User.Birthdate)">
But same result:
MvxBind ( 2574): 33.60 Failed to create target binding for binding Visibility for MvxValueConverterValueCombiner combiner-operation
I just took the birthdate as an example, but every Visibility bindings failed (I have x error messages for x bindings).
EDIT 1
The others binding work, I bind a bunch of text, and all display well:
<TextView
style="#style/TextView.ListWithIcon.Single"
android:layout_marginTop="#dimen/ListIconTwoLineTextMarginTop"
local:MvxBind="Text User.FirstName" />
I also try to bind to a INPC property, same result.
EDIT 2
As suggested by stuart, i tried this:
<TextView
style="#style/TextView.ListWithIcon.Single"
android:layout_marginTop="#dimen/ListIconTwoLineTextMarginTop"
android:layout_marginLeft="#dimen/ListIconTextMarginLeft"
local:MvxBind="Text Visibility(User.Birthdate)">
And the visibility converter on TextView seems to work, if Birthdate is null:
Birthdate: Gone
But it does not seem to bind to the visibility property:
<TextView
style="#style/TextView.ListWithIcon.SecondLine"
android:layout_below="#+id/Birthday"
local:MvxBind="Visibility Visibility(User.Birthdate)"
android:text="Whatever birthdate" />
Displays "Whatever birthdate" whereas Visibility(User.Birthdate) returns Gone...
EDIT 3
If you use Visible pseudo-property everything works as expected.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="#dimen/ListIconTwoLineTileHeight"
android:paddingRight="#dimen/ListIconTwoLineTextMarginRight"
local:MvxBind="Visible User.Birthdate">

I had the same issue with a LinearLayout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#color/white"
local:MvxBind="Visibility Visibility(IsLoading)">
Visibility of the LinearLayout wouldn't bind to my view model:
Failed to create target binding for binding Visibility for MvxValueConverterValueCombiner combiner-operation
Solution: add an entry to LinkerPleaseInclude.cs so the Visibility property isn't stripped from the view:
public void Include(LinearLayout layout)
{
layout.Click += (s, e) => layout.Visibility = layout.Visibility - 1;
}

There are 2 scenarios:
If you use MvvmCross 5 and below you need to use:
a) local:MvxBind="Visibility Visibility(User.Birthdate)" in your view
b) add a VisibilityPluginBootstrap.cs file in you Bootstrap folder that would look like this:
using MvvmCross.Platform.Plugins;
namespace YourNameSpace.Droid.Bootstrap
{
public class VisibilityPluginBootstrap
: MvxPluginBootstrapAction<MvvmCross.Plugins.Visibility.PluginLoader>
{
}
}
If you use MvvmCross 6 and above you need to use only:
local:MvxBind="Visible User.Birthdate" in your view
and don't need a Bootstrap file:

Related

a personal adapter error with observer pattern

I have a problem with my personal adapter. When I search through the Observer pattern for information in a local database, it brings me the records but the adaptare is not called until you make a second attempt to delete and add the same petra to search. If I change the letter I have to delete it and re-enter it a second time so that it shows the help as you see in the image.
If you could help me I would appreciate it.
First search
enter image description here
second search. I delete the letter and enter it again
enter image description here
as you can see, now it works correctly.
I don't understood why.
Function call observer:
fun searchCountry(cadena:String){
var chain_1 = ""
if(cadena.trim().isNullOrEmpty()){
chain_1 = ""
}else{
chain_1 = cadena.trim() + "%"
}
locationViewModel.locationSearch(chain_1)
locationViewModel.locations.observe(this, Observer { locationList ->
autoCompleteTextView.setAdapter(LocationAdapter(this,locationList as List<Location>))
})
}
VieModel:
#HiltViewModel
class LocationViewModel #Inject constructor(private val getLocationUserCase: GetLocationUseCase) : ViewModel() {
val locations = MutableLiveData<List<Location?>>()
fun locationSearch(chain:String){
viewModelScope.launch {
val locationLst: List<Location> = getLocationUserCase(chain)
if(!locationLst?.isNullOrEmpty()){
locations.postValue(locationLst)
}else{
}
}
}
}
Adapter:
class LocationAdapter(context: Context, locations: List<Location>) : ArrayAdapter<Location>(context, 0, locations) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.account_frg_user_create_location_items, parent, false)
getItem(position)?.let { location ->
view.findViewById<TextView>(R.id.txtCountry).apply {
text = location.nom_municipio
}
view.findViewById<TextView>(R.id.txtProvince).apply {
text = location.nom_provincia
}
}
return view
}
}
XML-adapter:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:maxHeight="56dp"
android:padding="16dp"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txtCountry"
android:layout_width="match_parent"
android:layout_weight="1"
android:textAppearance="#style/TextAppearance.MaterialComponents.Body1"
android:layout_height="wrap_content"
tools:text="Pueblo" />
<TextView
android:id="#+id/txtProvince"
android:layout_width="match_parent"
android:layout_weight="1"
android:textAppearance="#style/TextAppearance.MaterialComponents.Body2"
android:gravity="end"
android:layout_height="wrap_content"
tools:text="Provincia" />
</LinearLayout>
XML-Autocomepletetextview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<AutoCompleteTextView
android:id="#+id/autoCompleteTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:completionThreshold="1"
android:imeOptions="actionDone"
android:inputType="text"
/>
</LinearLayout>
It is expected that when I enter a letter for the first time, it will show the search help that does show if I delete and add the same letter again or enter two letters or more.
Finally, I found my mistake. What happened is that the component, AutoCompleteTextView, already performed the same function that it was doing with the addTextChangedListener, so it searched for the information on both sides. Finally, the solution is to remove the addTextChangedListener, and pass the complete list to the adapter, since it is the autocomplete that is in charge of carrying out the search that it did on the database.
fun iniciacilarBd(){
locationViewModel.locationSearch("%")
// <!-- BASE_DE_DATOS
locationViewModel.locations.observe(this, Observer { locationList ->
locations = locationList
LocationAdapter(this,locations).also { locationAdapter ->
autoCompleteTextView.setAdapter(locationAdapter)
}
})
}
Thanks for the help

How to Create a Custom Listview without extending List Activity?

I Want to Create a List View with a Custom layout which will contain A image and text
But all the tutorials i find all extend List Activity but i cant extend List Activity because i need to add buttons and other things to the layout.
I need to use the ListView using a custom item layout
any ideas on how to do it?
You are not bound to use ListActivity in order to have a ListView in your layout. All the samples using ListActivity are there because people are lazy ;)
So just use a regular Activity and then you simply have to add the ListView to the layout you are setting as content view. This could look something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="0"
android:layout_weight="1" />
<Button
android:id="#+id/somethingButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Do something" />
<Button
android:id="#+id/elseButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Do something else" />
</LinearLayout>
Then in like any other Activity in your OnCreate method you do:
SetContentView(Resource.Layout.myLayout); // myLayout.axml
var listView = FindViewById<ListView>(Resource.Id.listView);
listView.Adapter = new MyAdapter(context, itemsSource);
var somethingButton = FindViewById<Button>(Resource.Id.somethingButton);
var elseButton = FindViewById<Button>(Resource.Id.elseButton);
... more code ...
ListView is just a layout just like any other, so there is nothing magic about it. MyAdapter in this sample is ofcourse something you implement, which takes your data and presents it in the desired image and text layout.
For more information about ListView and Adapter please refer to the excellent documentation which Xamarin provides.

Is there any difference between ViewStub and View?

I am new to Android Development.
I read about ViewStub from https://developer.android.com/training/improving-layouts/loading-ondemand.html
It mentions that it is cheap and less memory to use it.
I have the following:
MainLayout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/Layout1"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#color/blue"
android:orientation="vertical" >
.....
.....
<Button android:id="#+id/ShowBackground"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
<Button android:id="#+id/ShowBackground2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="#string/title_close" />
<View
android:id="#+id/ShowView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/blue" />
<ViewStub
android:id="#+id/ShowViewStub"
android:layout="#layout/test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</RelativeLayout>
test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ShowViewLayout"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#color/blue_dimmer"
android:orientation="vertical" >
</RelativeLayout>
MainActivity:
private ViewStub mViewStub;
private View mView;
private Button mBackground1;
private Button mBackground2
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.MainLayout);
mView = (ViewStub) findViewById(R.id.ShowView);
mViewStub = (ViewStub) findViewById(R.id.ShowViewStub);
mBackground1 = (Button)this.findViewById(R.id.ShowBackground);
mBackground1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mView.setVisibility(View.VISIBLE);
}
});
}
mBackground2 = (Button)this.findViewById(R.id. ShowBackground2);
mBackground2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mViewStub.setVisibility(View.VISIBLE);
}
});
}
Questions:
View and ViewStub are working fine in the MainActivity.
I do understand ViewStub is good for the view that is rarely used.
If ViewStub is called at least 1 time in the MainActivity, shouldn't it be more memory usage since the test.xml layout is added to the activity?
As I can see is that ViewStub is always visible unless it is called View.Gone....
Can someone please explain what the differences between the two?
I greatly appreciate for your help,
Thank you.
The < include /> will just include the xml contents in your base xml file as if the whole thing was just a single big file. It's a nice way to share layout parts between different layouts.
The < ViewStub /> is a bit different because it is not directly included, and will be loaded only when you actually use it/need it, ie, when you set its visibility to VISIBLE (actually visible) or INVISIBLE (still not visible, but its size isn't 0 anymore). This a nice optimization because you could have a complex layout with tons of small views or headers anywhere, and still have your Activity load up really fast. Once you use one of those views, it'll be loaded.

ProgressBar multiple displaying

I have an AsyncTask linked to a refresh Button (when I click on my refresh button my AsyncTask is called).
I have on my Layout a LinearLayout field for my ProgressBar :
<?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"
android:background="#color/grey">
<Button android:id="#+id/refresh_p"
android:text="#string/refresh_promo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/custom_button1"/>
<LinearLayout android:id="#+id/linearlayoutProgressBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:listSelector="#color/tabTransparent"
android:cacheColorHint="#00000000"/>
<!-- <ListView android:id="#+id/list_promo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>-->
</LinearLayout>
In my AsyncTask :
#Override
protected void onPreExecute()
{
super.onPreExecute();
pb = new ProgressBar(context);
LinearLayout ll = (LinearLayout) ((Activity) context).findViewById(R.id.linearlayoutProgressBar);
ll.addView(pb);
pb.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(ArrayList<HashMap<String, String>> promoList)
{
...
if (pb!=null)
{
pb.setVisibility(View.GONE);
((LinearLayout)pb.getParent()).removeView(pb);
}
}
The problem I have is when I make more than 2 clicks on my Refresh Button then Multiple ProgressBar are displaying into the screen.. I just want that the new ProgressBar replace the old at the same position ..
My guess is that you are probably starting your AsyncTask in a manner similar to this:
new RefreshTask().execute(params);
Instead of that, create an instance variable in your activity. Let's say this is named mTask and substitute the above code for the following call:
if(mTask != null && mTask.getState != AsyncTask.State.RUNNING){
mTask = new RefreshTask();
mTask.execute(params);
}
This way you will ensure that only one instance of your task is running at a given time and the user will have to wait until the refresh is finished before he can start a new refresh.
If you want the user to be able to cancel an existing refresh task and run a new one, you will have to cancel the old one before starting a new one:
if(mTask != null){
if(mTask.getStatus() == AsyncTask.Status.RUNNING){
mTask.cancel(true);
}
mTask = new RefreshTask();
mTask.execute(params);
}
This way the old task and it's ProgressBar will be properly replaced by the new one.

Not able to set the background to a ListView

I am trying to set background for my List view . I have taken a image from the drawable and set it as background to the layout file then it is giving the result as following screen shot
and when i just remove the background am getting the thing which i required but no background.
and screen shot is
Is there is any other Syntax to set background for ListView.
And my Code for layout is
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:text="#+id/TextView01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/label"
android:textColor="#FF0000"
android:textSize="30px"></TextView>
</LinearLayout>
And my java code and that is
String[] names = new String[] { "India", "Malaysia" };
// Use your own layout and point the adapter to the UI elements which
// contains the label
this.setListAdapter(new ArrayAdapter<String>(this, R.layout.screen3,
R.id.label, names));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
Object o = this.getListAdapter().getItem(position);
String keyword = o.toString();
if(keyword.equals("India"))
{
Intent ima1=new Intent(screen3.this,new21.class);
startActivity(ima1);
}
else
{
Intent ima2=new Intent(screen3.this,new22.class);
startActivity(ima2);
}
Toast.makeText(this, "You selected: " + keyword, Toast.LENGTH_LONG)
.show();
}
And lastly i need is I want the background image with proper listview showing one listitem after another. Thanks in advance
}
Try this code, Instead of extending ListActivity you can set layout that contains List View and separate layout for contents of List View.
Java Code :
public class Table_Layout extends Activity {
ListView list_view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.table_layout);
list_view=(ListView)findViewById(R.id.list_view);
String[] names = new String[] { "India", "Malaysia" };
list_view.setAdapter(new ArrayAdapter<String>(this, R.layout.screen3,R.id.label, names));
}
}
Main XML that contains List View :table_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#drawable/uploading">
<ListView android:layout_width="fill_parent" android:layout_height="fill_parent"
android:id="#+id/list_view"
/>
Then Contents of List View :screen3.xml
<?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="wrap_content"
>
<TextView android:text="#+id/TextView01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/label"
android:textColor="#FF0000"
android:textSize="30px"></TextView>
</LinearLayout>
Set you Background for the table_layout.xml so that it will applied for entire List View as you expected.
All looks well with your xml file. Try implementing the below mentioned:-
Make an image of the size you want your listview's each row of. And set it as the parent LinearLayout's background. Set:- android:layout_width="fill_parent" android:layout_height="wrap_content".
Hope this helps !! :)

Resources