Fix #android:id/empty behavoir in ListFragment - android-listfragment

I'm using a cursor in a ListFragment with Views ListView #android:id/list and TextView #andoid:id/empty. Now, since a non closed cursor uses more akku performance, i want to close the cursor when i start a new activity. i put cursor.close() in onPause() of the ListFragment.
The problem is, when the cursor is closed, the TextView is shown for a short time before the new activity is getting started. This looks ugly and causes a short delay before.
Ive tried something like this:
if (cursor.moveToNext()){
tv = (TextView) getActivity().findViewById(android.R.id.empty);
tv.setVisibility(View.GONE);
}
But this didnt change anything. Even if the shown textview is gone, the delay would stay i guess...
Do u guys have a good way for me to solve the problem?
thanks in advance
pebbles
My Cursor:
public void loadCursor(){
cursor = getActivity().getContentResolver().query(ProgressContentUri, new String[]{Table.Columns._ID, Table.Columns.NAME, Table.Columns.DATE}, "", null, Table.Columns.DATE+ " DESC");
}

You can either try to close it in the onStop method of your fragment, or use a CursorLoader which is a much better way to use cursors.
This way the cursor will be loaded asynchronously and closed automatically.

Related

How to get info about completion of one of my animations in Unity?

I have monster named Fungant in my 2D platform game.
It can hide as mushroom and rise to his normal form.
I try to handle it in code, but I don't know how to get information about finished animation (without it, animation of rising and hiding always was skipped).
I think the point there is to get info about complete of the one of two animations - Rise and Hide.
There is current code:
if (
fungantAnimator.GetCurrentAnimatorStateInfo(0).IsName("Fungant Rise")
)
{
fungantAnimator.SetBool("isRising", false);
isRisen = true;
fungantRigidbody.velocity = new Vector2(
walkSpeed * Mathf.Sign(
player.transform.position.x - transform.position.x),
fungantRigidbody.velocity.y
);
}
if (fungantAnimator.GetCurrentAnimatorStateInfo(0).IsName("Fungant Hide"))
{
fungantAnimator.SetBool("isHiding", false);
isRisen = false;
}
I try this two ways:
StateMachineBehaviour
I would like to get StateMachineBehaviour, but how to get it?
No idea how to process this further.
AnimationEvents
Tried to do with animation event but every tutorial have list of functions to choose (looks easy), but in my Unity I can write Function, Float, Int, String or select object (what I should do?).
I decided to write test() function with Debug only inside, and create AnimationEvents with written "test()" in function field, but nothing happens.
Same as above, no more ideas how to process this further.
I personally would use animation events for this. Just add an event to the animation and then the event plays a function after the animation transition is finished.
For more information on how to use animation events you can click here.
This post may also help you to add an event when the animation is finished.
I hope this answer helps you to solve this problem.

SetAllDirty() not working at runtime in Unity?

Edit:
After doing a little more debugging I found that it doesn't work only when I start the game and have the panel/canvas that it sits on disabled. If I have the panel/canvas enabled the whole time then it redraws correctly. However, this obviously isn't a proper solution because I can't show the results before the end of the quiz. I need the panel to be disabled so that I can show it later after the end of the quiz.Is there a reason this is happening? How can I fix this?
End Edit
So I found a script on GitHub that basically creates a UI polygon. It works great in the Editor, however, I want to modify it at runtime. From everything I read all I need to do is call the method SetAllDirty() and it will update the MaskableGraphic and Redraw it. However, whenever I call it, nothing happens. SetVerticesDirty() also did not work. Can someone see where I am going wrong here.
All I am doing is calling DrawPolygon and giving it 4 sides, and passing a float[5] I modified it so that right after I finish setting up my new variables I call SetAllDirty()
Something like this:
public void DrawPolygon(int _sides, float[] _VerticesDistances)
{
sides = _sides;
VerticesDistances = _VerticesDistances;
rotation = 0;
SetAllDirty();
}
Like I said, it works fine in the editor(not runtime), and I am also getting all the values passed to the script correctly(during runtime), but it is not redrawing. As soon as I manipulate something in the inspector it will redraw to the correct shape.
The rest of the script is posted here:
https://github.com/CiaccoDavide/Unity-UI-Polygon/blob/master/UIPolygon.cs
This is the method that I call DrawPolygon from on a Manager script. I see in the log that it prints out the statement, Quiz has ended.
void EndQuiz()
{
Debug.Log("Quiz has ended.");
QuizPanel.SetActive(false);
ResultsPanel.SetActive(true);
float[] Vertices = new float[5] { score1, score2, score3, score4, score1};
resultsPolygon.DrawPolygon(4, Vertices);
}

MVVM, wait cursor while opening "slow" page

I have MVVM application with multiple pages. My all pages have ReadCommand() bound with:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding ReadCommand}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
This is my Read() command in ViewModel:
private void Read(object parameter)
{
HwDevice Device = new HwDevice();
this.Alarms = Device.Alarms; // this is slow (reading data from RS232 device)
Device.Dispose();
}
One page has slow data source and my application is frozen when this page is being loaded (about 5 seconds).
I want to set wait cursor on whole window, but I don't know how to do it in MVVM (Im MVVM newbie). Do I have to pass window reference by command parameter and set Wait cursor in command? If I should - how can I do it in XAML?
The problem is that the thread where you are going to execute your operation, is the same where your UI live. It's here that the BackgroundWorker come in handy.
BackgroundWorker bw = new BackgroundWorker();
bw.RunWorkerAsync += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_WorkDone
The previous part was the declaration. Now you need to implement the events, but first modify Read method
private void Read(object parameter)
{
bw.RunWorkerAsync(parameter);
// put your logic here
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
object parameter = e.Argument;
}
Now that the logic is placed on another thread, you can use the progressChanged method to do various stuff. Like showing a progress bar to report the status, or simply enable or disable your wait cursor.
EDIT: You don't need to pass the bw to the UI. If you are using MVVM (like you should and you are doing) you can use bindings and event at your advantage, or implement an interface like this one. The point of the whole thing is that the UI is just "informed" that something on the background is going on, avoiding to freeze the main thread. You just need to decide how to display it. So it can be either using a wait cursor, or implementing a progress bar.

EditorExit event handler called recursively

The below portion of my code caused recursive call on onEditorExit method. If I remove setData call, then no recursion occur.
What can be the workaround?
myGrid.addEditorExitHandler(new EditorExitHandler() {
public void onEditorExit(EditorExitEvent event) {
GWT.log("Hello");
myGrid.setData(new ListGridRecord());
}
});
Now check the console output -
Console Screenshot
It won't work because each time you call setData() the editor will fire an editorExit event in an infinite loop (not recursively). By the way, calling setData() in the way you are doing will replace all your records in the ListGrid with one new empty record. This seems like a disconcerting user experience.
It looks like you want to create and start editing a new record when you tab out of the last one. In order to do that in a ListGrid, you use:
grid.setListEndEditAction(RowEndEditAction.NEXT);
That's all you need to do in order to get it working.

GWT CellList Error: onSelectionChange, index out of bounds

I'm writing a messaging application in GWT, and have a fairly difficult problem to find a solution for. I'm working with a GWT CellList. In my cell list I'm displaying all the recent contacts a user has had recent communication with. But lets say that a user is writing a message to a person not on that list. I temporarily add them to the recentContacts list, and update the CellList so that it shows..
But then let's say that they end up not sending the message. I need to be able to detect that, and remove them from the list. The obvious place to do that is in the selection change handler. It actually turns out though that within a selection change handler, if can modify the list of data objects that represent the cell list, but when you actually push them to the cell list, I get an index out of bounds error.
I've verified that this is the issue. So basically I'm stuck. The obvious place to check this is when your selecting a different contact to view. I can then check if any messages were sent to this other contact, and if not, get rid of the contact, but I need to somehow not do it in the selectionChangeHandler. Does anyone have any solution/ideas? I tried a mouse up event, but that ends up happening before the selection event takes place.
Thanks for any help in advance :-)
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
public void onSelectionChange(SelectionChangeEvent event) {
ContactDO selectedContact = selectionModel.getSelectedObject();
//Check if we want to remove a contact from the list
if ( we want to remove a contact in the list that is not the currently selected contact. ) {
//remove contact
recentContacts.remove(contactThatisNotSelected);
//Refresh the contact cell list
contactCellList.setVisibleRange(0, recentContacts.size());
contactCellList.setRowCount(recentContacts.size(), true);
contactCellList.setRowData(0, recentContacts);
}
}
});
The solution that I implemented was just to use a Timer, and then do the work about 100ms later. Not really a fan of this solution. I'm still looking for another.