ViewBinding for an inner CustomView - android-custom-view

I have a next hierarchy of nesting for my views:
XML for a fragment has a MyCustomView1 inside.
MyCustomView1 creates MyCustomView2 programmatically inside (doesn't have it in XML) and uses it for setting up some parameter of MyCustomView1.
MyCustomView1 looks like:
class MyCustomView1 #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0) : ConstraintLayout(context, attrs, defStyle) {
val myCustomView2 = MyCustomView2(context, R.layout.my_custom_view_2)
init {
inflate(context, R.layout.my_custom_view_1, this)
...
}
fun setUpMyCustomView2() {
myCustomView2.view1 = ...
}
}
MyCustomView2 looks like:
class MyCustomView2(
context: Context,
layoutResource: Int) : BaseView(context, layoutResource) {
//...
}
MyCustomView2 XML file looks like:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myCustomView2Field"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
And I need to get myCustomView2Field in my fragment with using view binding but can't see it without proper view binding for this view inside. I see that I just need to make an appropriate view binding for this view but don't understand completely where to do it with this chain of inner dependencies.
Did someone face with the similar problem? How did you resolve it?

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 make Zebra Xing (Zxing) as subview in Xamarin Android

In my Xamarin.Android app, I want to use ZXing to scan barcode. I want to display the scanner in the view of an activity.
Code:
<?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"
android:weightSum="5">
<Button
android:text="Scan with Default Overlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/buttonScanDefaultView"
android:layout_weight="1" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/scanView"
android:layout_weight="2" />
</LinearLayout>
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
scannerFragment = new ZXingScannerFragment ();
scannerFragment.CustomOverlayView = CustomOverlayView;
scannerFragment.UseCustomOverlayView = UseCustomOverlayView;
scannerFragment.TopText = TopText;
scannerFragment.BottomText = BottomText;
this.FragmentManager.BeginTransaction ()
.Replace (Resource.Id.scanView, scannerFragment, "ZXINGFRAGMENT")
.Commit ();
}
I'm getting an error stating that I cannot convert support.v4.fragment into android.app.Fragment.
Can anyone advise what I'm doing wrong and how should I approach this to get the scanner view (of ZXing) in a layout of my current activity.
ZXingScannerFragment derives from Android.Support.V4.App.Fragment while the Activity.FragmentManager expects fragments derived from Android.App.Fragment.
Now, how to fix that:
Inherit your activity from any activity that works with Android.Support.V4. Easiest would to use Android.Support.V4.App.FragmentActivity from package Xamarin.Android.Support.v4 that is already installed by ZXing.Net.Mobile package as a dependency.
When you have correct activity, you can use this.SupportFragmentManager instead of this.FragmentManager to work with Support.V4-based fragments.
So, layout you have is good. Code should be updated to something like:
using Android.App;
using Android.Widget;
using Android.OS;
using ZXing.Mobile;
using Android.Support.V4.App;
namespace ZXingSample
{
[Activity(Label = "ZXing Sample", MainLauncher = true, Icon = "#mipmap/icon")]
public class MainActivity : FragmentActivity
{
int count = 1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
var scannerFragment = new ZXingScannerFragment();
scannerFragment.UseCustomOverlayView = false;
scannerFragment.TopText = "Scan your code";
scannerFragment.BottomText = "Then proceed";
this.SupportFragmentManager.BeginTransaction()
.Replace(Resource.Id.scanView, scannerFragment, "ZXINGFRAGMENT")
.Commit();
}
}
}
Launching the app, you will see your scanner:

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.

Flex Mate - PropertyInjector fired twice when mapped between Manager and View

My application uses Flex 4 and Mate framework 0.9.1. I'm facing an issue with the PropertyInjector being fired twice when there's a mapping between a manager and a view.
I have not shared the original code here, but it looks similar to the following:
Based on an event, a property (someData) in MyManager is updated. A property injector updates this new value in a target view (MyView). The issue is - when onDataChanged is invoked and the property someData is updated, the method "set someData" in the view is fired twice. I know that the view is instantiated only once because I have debugged the init and creationComplete events. The source property in MyManager is also updated only once as per the trace.
This would indicate that the property injector is fired twice. Would anyone know under what conditions this can happen? Any pointers would be appreciated!
MyEventMap.mxml
<EventHandlers type="{DataChangedEvent.GET}" debug="true">
<MethodInvoker generator="{MyManager}" method="onDataChanged"
arguments="{[event.x,event.y,event.name]}">
</MethodInvoker>
</EventHandlers>
<Injectors target="{MyView}" debug="true">
<PropertyInjector targetKey="someData" source="{MyManager}"
sourceKey="someData">
</PropertyInjector>
</Injectors>
DataHolder.as
public class DataHolder
{
public function DataHolder()
{
}
public var x:Number;
public var y:Number;
public var name:String;
}
MyManager.as
public class MyManager extends EventDispatcher
{
....
[Bindable] public var someData:DataHolder;
public function onDataChanged(x:Number,y:Number,name:String):void{
trace("dataChanged");
var temp:DataHolder = new DataHolder();
temp.name=name;
temp.x=x;
temp.y=y;
someData = temp;
}
}
MyView.mxml
public function set someData(data:DataHolder):void {
trace("setSomeData x="+data.x+",y="+data.y+",name="+data.name);
}
I found the problem is due to a combination of BabelFX 2.0 and Mate framework 0.9.1. Below is the BabelFX related code. Using MyView as a target of the ResourceInjector causes all PropertyInjector's related to it being fired twice. Is there an issue in the code below?
testLocalization.mxml:
<?xml version="1.0" encoding="utf-8"?>
<LocaleMap enableLog="true"
xmlns="http://l10n.babelfx.org/"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:factory="mx.core.*" >
<mx:Metadata>
[ResourceBundle("testprop")]
</mx:Metadata>
<ResourceInjector bundleName="testprop" target="{MyView}">
<ResourceSetter property="myButton.label" key="testsomething.title"/>
</ResourceInjector>
MyView.mxml (also the main app)
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:local="*"
xmlns:mate="http://mate.asfusion.com/">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<mate:Debugger level="{Debugger.ALL}" />
<local:testLocalization/>
<local:MyEventMap/>
</fx:Declarations>
<s:Button id="myButton">
</s:Button>
</s:Application>
testprop.properties
testsomething.title = SOMETHING

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