Listview with CursorAdapter getCheckedItemIds not returning _ids - android-cursoradapter

Listview with CursorAdapter
SetchoiceMode is multiple
getCheckedItemIds is returning position rather than _ids
and my adapter is also stable
do you know the reason ?

My cursor adapter had overridden below method
#Override
public long getItemId(int position) {
return position;
}
i deleted this, now its working fine

Related

Load Data lazily from firestore document in Flutter

For performance increase I want to load the data from a firestore document lazily. Therefore I use a PaginatedDataTable. In the rowList I have all the data from a firestore document which I want to show in the PaginatedDataTable. My question is does the lazy Loading from PaginatedDataTable work with Firestore?
/// DataTable Source
class DTS extends DataTableSource {
List<DataRow> rowList;
DTS(List<DataRow> rowList) {
this.rowList = rowList;
}
#override
DataRow getRow(int index) {
return this.rowList[index];
}
#override
int get rowCount =>
this.rowList.length;
#override
bool get isRowCountApproximate => false;
#override
int get selectedRowCount => 0;
}
From what I can quickly tell the standard PaginatedDataTable/DataTableSource classes don't natively support Firestore or any specific data source, but you'll have to implement those bindings yourself.
Explaining how to do that is a bit beyond what we can typically do here on Stack Overflow, but this search shows some promising results.

Rebuild a widgets in searchdelegate flutter

I want to rebuild the buildSuggestions method that returns a widget that the defined below
and resultInfo getting the result from TMDB API search that a string as an input
how can i recall the resultInfo and rebuild it.
#override
Widget buildSuggestions(BuildContext context) {
if (query.length > 1) {
return ResultInfo(s: query);
}
return ResultInfo(s: "old");
//ResultInfo not updating after the query updates
}
this is the home screen code where searchdelegate is defined and here you can find the code for ResultInfo widget.
UPDATE: After looking at the project, you need to call the getMovies function from the buildSuggestions build method because initState was only getting called once despite the rebuilds. Add this and you're good.
#override
Widget buildSuggestions(BuildContext context) {
if (query != '') {
searchResult.getMovies(query); // do the search from here
return ResultInfo(searchString: query);
}
return ResultInfo(searchString: "old");
}
}
You can leave the search in initState also so you don't get a blank list when you navigate to the search page.
OLD ANSWER:
Any time the query changes in a widget that extends SearchDelegate, buildSuggestions is called. You can verify that by adding a print statement in the buildSuggestions build method.
I see a couple issues here:
class ResultInfo extends StatefulWidget {
final String s;
ResultInfo({Key key, #required this.s}) : super(key: key);
#override
_MovieInfoState createState() => _MovieInfoState(s);
}
class _MovieInfoState extends State<ResultInfo> {
// final String s; don't need this here
_MovieInfoState(this.s);
#override
void initState() {
super.initState();
searchResult.getMovies(widget.s); // access the actual parameter you passed in with widget.s
}
When you pass a value into a stateful widget you don't re-declare the same value again in the stateful part, you access what was passed in with widget.variable. So in your case you were passing in a null value into the getMovies function.
So assuming your stream functionality is all working, that simple change alone should fix your issue.
And in the interest of your code being readable by other people, I suggest a better variable name than s, like query for example because that's what it is. Anyone reading your code has no idea what s is and what it's for until they dig around a bit.
Second issue:
if (query.length > 1) { // won't return results until 2nd character is input
return ResultInfo(s: query);
}
return ResultInfo(s: "old");
}
Maybe its your intention to only return ResultInfo(s: query) until more than one character is input, but if its not, change your condition to this
if (query != '') {
return ResultInfo(s: query);
}
return ResultInfo(s: "old");
}

Flutter Provider, using child widget to update a list

I'm new to using Flutter and I am currently struggling to understand how to use the Provider package for the following task, or if it is even the correct implementation in the first place.
I have a widget that uses another widget within itself to update a time value.
In the parent widget I have the following:
class _AddTimesScreenState extends State<AddTimesScreen> {
List<TimeOfDay> times = [];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Provider<List<TimeOfDay>>.value(
value: times,
child: SetTimes()
In the 2nd widget, which is used to update the times list by using a time picker I have:
class _SetTimesState extends State<SetTimes> {
#override
Widget build(BuildContext context) {
final times = Provider.of<List<TimeOfDay>>(context);
Essentially my goal is to be able to update the times list in the 2nd widget so it can then be used in the first widget. I have methods to add TimeOfDay objects to the list, but when the code is run the list in the first widget does not appear to be updated.
Am I using Provider in a way that it's intended, or have I completely misunderstood its application?
Thanks
In the TimeOfDay class make sure you are extending it with Change Notifier.
How does provider know it has to rebuild?
When the class (TimeOfDay in your case) extends ChangeNotifier, you are provided with a method called notifylisteners() , this triggers a rebuild to all the widgets consuming the provider. So you should call this in the function that is changing the objects data in your class TimeOfDay.
So make sure you are:
extending ChangeNotifier in your class/model.
calling notifylisteners when data is changed.
Example :
class MyClass extends ChangeNotifier{
int a = 0;
addSomething(){
//Here we are changing data
a = a + 1;
notifylisteners();
}
}
let me know if this solves your error.

Bloc: is it possible to yield 2 time the same state?

In the login view, if the user taps on the login button without having inserted his credentials, the LoginFailState is yield and the view reacts to it. If he taps again, this LoginFailstate is yield again, but the view doesn't react to it. So, is there a way to yield more times the same state?
There is some code to better explain my situation:
class LoginBloc extends Bloc<LoginEvent, LoginState> {
#override
LoginState get initialState => LoginUninitialized();
#override
Stream<LoginState> mapEventToState(LoginEvent event) {
if (event is loginButtonPressed) {
yield LoginFailState();
}
}
View:
#override
Widget build(BuildContext context) {
return BlocBuilder(
bloc: _loginBloc,
builder: (BuildContext context, LoginState state) {
if (state is LoginFail) {
print ('Login fail');
}
return Column(
...
)
You can receive an update for the "same" State if you don't extend Equitable, or implement your own '==' logic which makes the two LoginFailStates equal.
The solution is to yield a different State in between, like in the Bloc example.
yield LoginLoading();
It gets called on every login button tap. Felangel's LoginBloc example.
By default BLoC pattern will not emit state when the same state will be passed one after another. One way to do this is to pass your initial BLoC state after passing LoginFailState.
So after user clicks on the button with wrong credentials passed states will not be:
LoginFailState()
LoginFailState()
but
LoginFailState()
LoginEmptyState()
LoginFailState()
LoginEmptyState()
Which will make UI react to each of them.
But I think that the best and cleanest solution is to pass LoadingState from BLoC before passing LoginFailState().
You can follow the blog post that I have recently written regarding this topic.
Problem
When you try to emit a new state that compares equal to the current state of a Bloc, the new state won't be emitted.
This behavior is by design and is discussed here.
When I say "compares equal" I mean that the == operator for the two state objects returns true.
Solution
There are two proper approaches:
Your state class should NOT extend Equatable. Without Equatable, two objects of the same class with the same fields will NOT compare as equal, and this new state will always be emitted.
Sometimes you need your state class to extend Equatable. In this case, just add the result of the identityHashCode(this) function call to your props getter implementation:
class NeverEqualState extends Equatable {
#override
List<Object?> get props => [identityHashCode(this)];
}
Note that I use identityHashCode that works regardless the operator == is overloaded or not. In contrast, hashCode will not work here.
Warning:
Do not use random values in the getter implementation List<Object> get props => [Random().nextDouble()];. Random variables are random, meaning that with extremely low probability you still might get two equal values in a sequence that will break this workaround. This is extremely unlikely, so it's not possible to reproduce and debug this.
You can and should include fields in your get props implementation, but keep in mind that when all fields compare as equal the objects will also compare as equal.
Emitting some other state in-between two equal states works but it forces your BlocBuilder to rebuild part of UI and BlocListener to execute some logic. It's just inefficient.
Finally, why would you like to have a state class extend Equatable but still not compare equal? This might be needed when your state class is actually the root of a hierarchy, where some descendants need to implement the == operator properly, and some need to never compare equal. Here is the example:
class BaseMapState extends Equatable {
const BaseMapState();
#override
List<Object?> get props => [];
}
class MapState extends BaseMapState {
final Map<String, Report> reports;
final Report? selectedReport;
final LatLng? selectedPosition;
final bool isLoadingNewReports;
const MapState(
{this.reports = const {},
this.selectedReport,
this.selectedPosition,
this.isLoadingNewReports = false});
#override
List<Object?> get props => [
...reports.values,
selectedReport,
selectedPosition,
isLoadingNewReports
];
}
class ErrorMapState extends BaseMapState {
final String? error;
const ErrorMapState(this.error);
#override
List<Object?> get props => [identityHashCode(this), error];
}
class NeedsAuthMapState extends ErrorMapState {
const NeedsAuthMapState() : super('Authentication required');
}
class NoInternetMapState extends ErrorMapState {
const NoInternetMapState() : super("No Internet connection");
}
If you use Equitable and tries to emit two equal instances of the same State with different properties, make sure that you override props array. By overriding props array, Equitable will know how to compare state instances.
class TablesLoadedState extends Equatable {
final List<TableEntity> tablesList;
TablesLoadedState(this.tablesList);
#override
List<Object> get props => [tablesList];
}
So, when bloc emits two instances of the same state with different values, these state-instances will be passed to BlocListener and UI will be updated according to new data.
A late possible workaround would be adding a random double to the state get props, this way the state won't be equal and you can yield them one after the other if you want.
also, Random().nextDouble() complexity is O(1) so you don't need to worry about performance
class LoginFailState extends LoginState {
#override
List<Object> get props => [Random().nextDouble()];
}

GWT widget with JSNI not attached yet

I created a widget that extends SimplePanel and execute some JSNI in onLoad() method:
public class AceEditor extends SimplePanel implements HasText {
private JavaScriptObject editor;
#Override
protected void onLoad() {
super.onLoad();
editor = createEditor(getElement());
}
private static native JavaScriptObject createEditor(Element element) /*-{
return $wnd.ace.edit(element);
}-*/;
#Override
public native void setText(String value) /*-{
this.#org.obiba.opal.web.gwt.ace.client.AceEditor::editor.setValue(value);
}-*/;
#Override
public final native String getText() /*-{
return this.#org.obiba.opal.web.gwt.ace.client.AceEditor::editor.getValue();
}-*/;
}
The problem is when I call setText for the first time, the widget is not attached yet (onLoad was not called yet).
I use this widget with UiBinder.
I could use addAttachHandler and check if the widget is attached but it does not seem the right way to do it...
Any idea of why the widget is not attached sooner?
Can you put the call to createEditor in the constructor instead of onload ?
It seems that your code is calling the setText before the page is loaded.
Now if that is the case calling createEditor in the constructor should be proper.
Any idea of why the widget is not attached sooner?
By definition, it shouldn't be 'attached' until after you've added it to an already-attached parent (either to RootPanel, or another thing already added to RootPanel). Have you done so and onLoad still isn't called?
If your JS tool (in this case ace) requires that a DOM node exists, then you don't need to wait for onLoad to be called to do anything - as of your Widget subclass's constructor being finished, you must already have specified an element.
If you actually require that this element is attached to the document before you can perform operations on it, then yes, of course, you need to wait until onLoad is called.