Search code examples
androidobjective-candroid-animationporting

Convert a piece of iOS code to Android


I think from the title this question is a little bit confusing and will attract many (-) but you will see that its very interesting.

I have code my nice app for iOS and with a friend we want to port it in Android. Everything went ok except from a piece of code.

In my iOS app i have a UIView shown when UIWebview is loading,animating it.When UIWebview is finished loading i have it hidden. The animation i made with the animateWithDuration function. Here we are:

The UIView:

@property (nonatomic,retain) IBOutlet UIView *animationLayer;
_animationLayer.hidden=YES;

Initialize it in Viewdidload

_animationLayer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
    _animationLayer.backgroundColor=[UIColor colorWithRed:(arc4random() % 255)/255.0f green:(arc4random() % 255)/255.0f blue:(arc4random() % 255)/255.0f alpha:1.0f];
    _animationLayer.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

On loading show the UIView and start animating it:

- (void) webViewDidStartLoad:(UIWebView *)webView {
[UIView animateWithDuration:7.0
                      delay:0.0
                    options: UIViewAnimationOptionCurveEaseOut
                 animations:^{ _animationLayer.backgroundColor=[UIColor colorWithRed:(arc4random() % 255)/255.0 green:(arc4random() % 255)/255.0 blue:(arc4random() % 255)/255.0 alpha:1.0f];}
                 completion:nil];
}

Hide it on finish loading

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    _animationLayer.hidden=YES;
}

Here's how i think it could be made in Android. Have a customized progressbar shown on loading and hidding it when done. The progressbar could be customized in a fullscreen canvas which changes it's color like the iOS code above.But no luck! :( Any suggestion or an easy way to do it?

Thanks!


Solution

  • Ok in order to get an animation going for Android in the background while web call is being made, use AsyncTask. It looks like this

       private class WebCallOperation extends AsyncTask<String, Void, String>
            {
                private final ProgressDialog dialog = new ProgressDialog(context);
    
                @Override
                protected String doInBackground(String... params)
                {
    
                    //web call code here
    
                    //response returned here
                    return "";
                }
    
                @SuppressWarnings("rawtypes")
                @Override
                protected void onPostExecute(String result)
                {
                    if (this.dialog.isShowing())
                    {
                        this.dialog.dismiss();
                    }
                }
    
                @Override
    
    
    protected void onPreExecute()
            {
                this.dialog.setMessage("Loading");
                this.dialog.show();
            }
        }
    

    In the example code I have just given, I have added the ProgressDialog in, this is usually what I use while making a web call, however you can replace that with whatever you want. You can add your own view in, and animate that instead. Animate it in the pre execute method, then finish the web call in the post execute method.

    Bit of advice on the IOS app, I mentioned in the comment already about the duration issue. I also think you should research block code for carrying out web calls. If you wish I can provide some example code, would make life a lot easier for you

    EDIT:

    Objective-C Block code. Create this class here

    Interface class

    #import <Foundation/Foundation.h>
    #import "WebCall.h"
    
    @interface WebCall : NSObject
    {
        void(^webCallDidFinish)(NSString *response);
    
    }
    
    @property (nonatomic, retain) NSMutableData *responseData;
    
    -(void)setWebCallDidFinish:(void (^)(NSString *))wcdf;
    
    -(void)webServiceCall :(NSString *)sURL_p : (NSMutableArray *)valueList_p : (NSMutableArray *)keyList_p;
    
    @end
    

    Implementation class

    #import "WebCall.h"
    #import "AppDelegate.h"
    @implementation WebCall
    
    @synthesize responseData;
    
    -(void)setWebCallDidFinish:(void (^)(NSString *))wcdf
    {
        webCallDidFinish = [wcdf copy];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
        int responseStatusCode = [httpResponse statusCode];
    
        NSLog(@"Response Code = %i", responseStatusCode);
        if(responseStatusCode < 200 || responseStatusCode > 300)
        {
            webCallDidFinish(@"failure");
        }
    
    
    
        [responseData setLength:0];
    }
    
    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
    {
    
        return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
    {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    
        [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        [responseData appendData:data]; 
    }
    
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
    
        NSLog(@"WebCall Error: %@", error);
        webCallDidFinish(@"failure");
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
    
            NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
            response = [response stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            webCallDidFinish(response);
    
    }
    
    -(void)webServiceCall :(NSString *)sURL_p : (NSMutableArray *)valueList_p : (NSMutableArray *)keyList_p
    {
        NSMutableString *sPost = [[NSMutableString alloc] init];
    
        //If any variables need passed in - append them to the POST
        //E.g. if keyList object is username and valueList object is adam will append like
        //http://test.jsp?username=adam
        if([valueList_p count] > 0)
        {
            for(int i = 0; i < [valueList_p count]; i++)
            {
                if(i == 0)
                {
                        [sPost appendFormat:@"%@=%@", [valueList_p objectAtIndex:i],[keyList_p objectAtIndex:i]];
                }
                else
                {
    
                        [sPost appendFormat:@"&%@=%@", [valueList_p objectAtIndex:i], [keyList_p objectAtIndex:i]];
                }
            }
        }
    
    
        NSData * postData = [sPost dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
        NSString * postLength = [NSString stringWithFormat:@"%d",[postData length]];
    
    
    
        NSURL * url = [NSURL URLWithString:sURL_p];
        NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [request setHTTPMethod:@"POST"];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody:postData];
    
        NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    
        if (theConnection)
        {
            self.responseData = [NSMutableData data];
        }
    
    
    }
    
    @end
    

    Then you to make this web call, you call it like this

     WebCall *webCall = [[WebCall alloc] init];
    
    
        [webCall setWebCallDidFinish:^(NSString *str){
    
            //This method is called as as soon as the web call is finished
            NSLog(@"%@", str);
        }];
    
    
        //Make web call here
        [webCall webServiceCall:@"http://www.bbc.co.uk/" :nil :nil];
    

    See the setWebCallDidFinish method, it will not be called until the webcall has finished. So if you need to execute some code as soon as the web call as finished, such as stopping the animation, call it in that method there. Hope that helps