Scrolling to end of list with NetworkImageView Volley - android-listview

I am creating a chat view and loading images in a chat room using NetworkImageView (placed inside a Normal ListView) via Android Volley Framework, which works great but the problem is that when the chat gets loaded the images are downloaded after a while due to which scrolling to the bottom does not work as expected. What I want is the listview in which the images are kept should scroll to the end upon getting initialized.
Here is the code that does the scrolling to the bottom of the list:
listview.clearFocus();
listview.post(new Runnable() {
#Override
public void run() {
listview.setSelection(listview.getCount() - 1);
}
});
However, this does not scroll to the end of list. The issue is that volley does not load up the image by the time it is initialized and only initializes it when it is starting to get displayed (onAttachToWindow or onLayout calls). Refer to the code
A workaround to make sure the list gets scrolled is:
networkImageView.setImageResource(R.drawable.placeholderImage);
Although not a good solution, this gets the job done.
Anyone has better ideas?

Using setStackFromBottom(true) solves the issue. I don't know why it never came to my mind. Anyways, putting the question for people like me, having issues with volley.

Related

Would having multiple compasses in one app work?

I'm new to flutter so I apologize if this seems extremely easy to solve. I'm making an app which uses two compasses. They are put into two separate pages. When I open up the first page, the first compass works just fine. However, when I open up the second page, the second compass moves for a bit then completely stops working. When I try going back to the first page, the first compass stops working as well. I think this is because both compasses uses the same stream but I'm not too sure. The code to make the compasses I took from here: https://pub.dev/packages/flutter_compass/example. Can anyone help?
From what you have stated there can be 2 suggestive solutions from me that could for you:
You are not disposing the stream using the dispose method
#override
void dispose() {
compassController.close();
super.dispose();
}
If disposing the stream also does not work you can use Navigator.pushReplacement instead of Navigator.push which will remove the previous screen because when you push and pop the elements are not disposed(I'm still figuring the reasons behind this)

Back and volume buttons not working when app is resumed in certain conditions

I'm starting a new activity to display a leaderboard in my Android App.
When the leaderboard activity is displayed, and the user presses the home key and then resumes the app (so the leaderboard activity comes up again), and then navigates back to the main activity by pressing the back key, the back key and volume keys stop working).
I've attempted to override onBackPressed in my activity class. I can confirm that when this problem occurs, onBackPressed is not called (When back / volume is working, pressing back does trigger onBackPressed).
Normally I get a message in LogCat when I press the back key 'Unimplemented WebView method onKeyDown called from android.webkit.WebView,onKeyDown(WebView.java.2178)' - Again I can confirm that this message doesn't come up when the back key isn't working
Armed with the above information, I can only assume that it's something to do with the View not having focus or something along those lines. I would point out that touch input on the screen itself does work. It just seems to be the back and volume keys/buttons that have no effect.
It's an openGL ES 2.0 app so in my onPause() I'm calling view.onPause(); and in onResume, I'm calling view.onResume();
I really have no idea what's going on and I've been on this for 3 days straight so if anyone can point me in the right direction, that would be great.
If the user comes out of the leaderboard and back into the main app before they press the home key, then everything is OK, it's just if the home key is pressed while the leaderboard activity is displayed as described above.
So when I'm at the point where the back / volume keys aren't working, if I click my scores button and fire up the leaderboard activity again, they work. On returning to my activity, they stop working again.
Not sure if this is relevant at all but the following shows how I'm starting my leaderboard activity:
if (scoresButtonPresses){
displayLeaderBoard();
}
void displayLeaderBoard(){
//Display the leaderboard if already signed in
if (checkSignedIn()){
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), leaderboardID), 1);
}
//if not already connected, then set flag and connect to play services before displaying leaderbaord
else{
signInAction=SHOW_LEADERBOARD;
getGameHelper().beginUserInitiatedSignIn();
}
}
#Override
public void onSignInSucceeded() {
//If the flag is set, then display the leaderboard
if (signInAction==DISPLAY_LEADERBOARD){
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), leaderboardID), 1);
}
//Otherwise, reset the flag and take no action
else {signInAction=NO_ACTION;}
}
This is driving me crazy so any help or even a nudge in the right direction would be very much appreciated!!
Edit
After much testing I have learned a couple of things:
If I remove the view.onPause() && view.onResume() the problem seems to go away. So this appears to be something to do with the way key events are captured by the view. Pausing and resuming seems to mess something up.
I have also tried removing the view.onPause() and view.onResume() as above, but instead, putting in View.setVisibility(View.GONE); and then making it visible again in public void onWindowFocusChanged(boolean hasFocus). Again, I get the same problem. Interestingly, when I open the leaderboard, as expected the view's staus is 'gone' then hitting the home key and running the app again, it's set back to 'visible' - I don't understand this behaviour but I'll ask another question for that.
Lastly, and this I find really odd. If I put my app back to as I had it, then after hitting the home key and relaunching the app via Eclipse (and I can do this multiple times) the problem doesn't seem to occur. So in that respect, it appears to be something to do with touching the screen.
Edit
It appears as though this isn't limited to my app. I've tested this on a couple of other apps from the Play store and get the same result.
One app clearly uses a single activity model like mine and the back and volume stop working throughout the app.
The other may use a different activity for it menu and game. When I test on this app, the back/volume breaks but if you start a game (therefore a second activity), the back key starts working again, even when you return to the first activity (recreated this activity?!)
So maybe I can get around this by ensuring the activity is recreated? I thought i was already but maybe I'm not getting something. Maybe it's something to do with the stack.........
I have no solution to your problem but some additional insights since I'm facing the same bug/problem with the leaderboards and the back button (and it's driving me crazy).
I'm using a single activity with fragments from which I login to Google Play, open Leaderboards and Achievements in the exact way you are doing it (startActivityForResult). Always when I come back from any Google Play Service activity my back button is broken. Sometimes it's even enough if I try to login to Google Play for it to break, meaning the login popup sometimes breaks the back button (but not always).
Some more insights which might help to solve the problem:
I'm not using OpenGL, so it's not related to this - I'm just using a single activity and fragments
It's also breaking for me when I just use the back button for going back from any Google Play Activity (I don't even need to go via the home key, just normal back is enough).
When the back button is broken the Activity is not receiving any Key Events (OnKeyDown, OnKeyUp, dispatchKeyEvent) are all not working, although using the activity and touching it fully works. My guess is that some view is catching the events...
Edit:
I also tried checking activity.getCurrentFocus() and activity.hasWindowFocus() as well as the parent and context classes of activity.getCurrentFocus() to see if there is any difference between when it's working and when it's not - and there isn't any difference...
Edit:
It seems that a simple call to View.requestFocus() is fixing the problem. For my single activity (using fragments implementation) I have now added:
#Override
public void onResume(){
super.onResume();
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragmentContainer);
fragment.getView().requestFocus();
}
and this seems to be fixing the problem. Sill have to do long term checking if it's always fixed. In your OpenGL implementation I guess you will have to get the main view of the activity in some other way since you are not using fragments.
I know it's pretty old question, but for clarification: accepted answer is correct, but incomplete. Focus requesting should be done in onResume, onActivityResult, onSignInSucceeded and onSignInFailed. In first two you have! to call super. Some code:
private void requestFocusAfterGooglePlay(){
if(gimmeFocus==null)
return;
View currFocus=getCurrentFocus();
gimmeFocus.setFocusableInTouchMode(true);
gimmeFocus.setFocusable(true);
gimmeFocus.requestFocus();
gimmeFocus.setFocusableInTouchMode(false);
gimmeFocus.setFocusable(false);
if(currFocus!=null)
currFocus.requestFocus();
}
#Override
public void onSignInFailed() {
requestFocusAfterGooglePlay();
}
#Override
public void onSignInSucceeded() {
requestFocusAfterGooglePlay();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
requestFocusAfterGooglePlay();
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onResume(){
super.onResume();
requestFocusAfterGooglePlay();
}
in my case gimmeFocus is a dummy View created as below:
<View
android:id="#+id/gimme_focus"
android:layout_width="0px"
android:layout_height="0px"
android:focusable="false"
android:focusableInTouchMode="false"/>
I have dynamic layout so I can't never be sure that any view exists in my layout, so I've created this dummy View, it might be also added programmatically. You might choose your fixed View for gaining focus, but rembember that changing focus might change view's look (drawable state).

Custom VerticalSeekBar onSeekBarChangeListener implementation

I have implemented the VerticalSeekBar using this unbelievably simple solution here: How can I get a working vertical SeekBar in Android?
The problem is, I can't seem to set an onseekbarchangelistener in my UI Activity that uses this class. I can't for the life of me understand how to do this. I can do it from within the VerticalSeekBar class: if I add code inside the onTouch() method, it works.
However I need an onTouch listener in my Activity.
P.S. is there a particular reason why Android doesn't have a native vertical seekbar? Considering most phones are naturally portrait-mode devices, it makes sense to have bars running along the the length rather than the width of the screen. I have tried many VerticalSeekBar solutions from stackoverflow (love this site!), but the only solution that centers my SeekThumb graphic is the link supplied above. I have been working on getting a perfect vertical seekbar for months now. Any help would be a humansend!
in VerticalSeekBar class, comment out this whole part:
#Override
public void setOnSeekBarChangeListener(OnSeekBarChangeListener mListener) {
this.myListener = mListener;
}
instead you can do this
SeekBar sb = (SeekBar)findViewById(R.your.id);
sb.setOnSeekBarChangeListener(this);
Eclipse would underline it and ask you to implement onseekbarchangelistener, you do that and implement the methods and you are good to go
Good Luck !

Get the GWT ScrollPanel to start its vertical scrollbar at the bottom

I know there are some questions out there about the GWT ScrollPanel and how it works, but allow me to explain the situation.
I'm working on a project to implement QoS on routers. I'm now at the developping stage of the project and I need to make a webinterface to add protocols such as ssh and http and give them their bandwidth.
To save memory usage and network traffic, I do not use GWT-EXT or Smart GWT. So to set the bandwidths I use a ScrollPanel with an empty SimplePanel in it (which is way too big), leaving only the scrollbar.
Now here's the problem:
I want each scrollbar for each added protocol to start at the bottom, not the top. I can get it working through the code if I manually move the scrollbar first, then any function works, like a scrollToBottom(), or a setScrollPosition(). If I want to move scrollbars through code before moving the scrollbar manually, however, I can't call a function on it.
(I would post a picture but I can't yet - new user)
Summary:
So if I add a protocol (using a button called btnAjouter), the two slidebars (One for guaranteed bandwidth and one for the maximum bandwidth) for each protocol start at the top. I want them to start at the bottom on the load of the widget.
Is there a way to do this?
Thanks in advance!
Glenn
Okay, my colleage found the solution. It's a rather dirty one, though.
The thing is, the functions only work when the element in question is attached to the DOM. I did do a check with a Window.alert() to see if it was attached, and it was. But the prolem was that the functions were called to early, for example on a buttonclick it would've worked. The creation and attachment of the elements all happens very fast, so the Javascript can't keep up, this is the solution:
Timer t1 = new Timer()
{
#Override
public void run()
{
s1.getScroll().scrollToBottom();
s2.getScroll().scrollToBottom();
}
};
t1.schedule(20);
Using a timer isn't the most clean solution around, but it works. s1 and s2 are my custom slidebars, getScroll() gets the ScrollPanel attached to it.
You can extend ScrollPanel and override the onLoad method. This method is called immediately after a widget becomes attached to the browser's document.
#Override
protected void onLoad() {
scrollToBottom();
}
Could you attach a handler to listen to the add event and inside that handler do something like this:
panel.getElement().setScrollTop(panel.getElement().getScrollHeight());
"panel" is the panel that you add your protocol to. It doesn't have to be a ScrollPanel. An HTMLPanel will work.
You can wrap this method in a command and pass it to Schedule.scheduleDeferred if it needs to be called after the browser event loop returns:
Schedule.scheduleDeferred(new Scheduler.ScheduledCommand(
public void execute() {
panel.getElement().setScrollTop(panel.getElement().getScrollHeight());
}
));

GWT 2.0.3 on IE8 image LoadHandler Not Called intermittently

has anyone encountered a problem where you register a LoadHandler on the image, and when the image is loaded the LoadHandler doesn't get called sometimes? Is there some voodoo to make it work? Like some ridiculous order of initialization? This is driving me nuts.
The code works on Firefox, Chrome, IE6 and IE7. The image is attached to the DOM (I know LoadHandler won't get called if the image is not attached).
Edit
I have reduce the larger code to the following snippet.
private void loadNext() {
if (count < urlList.size())
Image displayImage = new Image();
displayImage.addLoadHandler(new ImageLoadHandler());
displayImage.addErrorHandler(new ImageLoadError());
mainPanel.add(displayImage);
displayImage.setUrl(urlList.get(count));
return;
}
}
private class ImageLoadHandler implements LoadHandler {
public void onLoad(LoadEvent event) {
count ++;
Log.TRACE("Success");
loadNext();
}
}
private class ImageLoadError implements ErrorHandler {
public void onError(ErrorEvent event) {
Log.ALERT("Error");
}
}
So basically this loads images one by one once the previous one has finished loading. The problem that occurs is the first image shows up as red x in IE8 and an error is caught. Now, if I right click on the image and click "show picture" it shows up, and triggers something such that the onLoad event is fired and the rest of the images load without errors! Now all of a sudden onLoad event works, all the other images which are same type are no longer an error.
the urlList is a list of urls to the images. The URL does not contain an extension for image type. The URLs go to a servlet which generate an image. I have taken care to set the proper Content-type headers (image/jpeg) in the response.
Furthermore, if I right click on the broken image, IE8 shows that it doesn't know its type. If I copy the URL, paste it in the address bar, IE loads the image just fine on its own. Now it seems to know the type when it's not in tags.
Very frustrating.
Thanks.
I encountered the same problem, after several days of inspection we found that it is internal bug of IE8 with its image cache. Try to delete complete browser history if it works for the first time. If it is your case then working solution is to add dummyParam to every image URL (with value e.g. new Date().timeInMilis() or something similar). I made this param enabled for user.agent=ie8 only.
I am really afraid of IE9 :(.
It turned out that this is a known GWT Bug.
Updating to GWT 2.1 should solve the problem.