Alright, I have made the appropriate changes to my SeqSwitch class so
that I no longer call setBackgroundResource from my onDraw (and in
fact no longer override onDraw at all).  Now, Mark, I have written an
audio pattern playback implementation using a Handler that runs in my
main Activity and, while it works, it is way less smooth and reliable
than the implementation using the Timer/separate thread.  I tried to
wade through the docs for AsyncTask and I could not tell whether or
not it would allow me to update the UI from my separate Timer thread.
Will it, or do I just have to choose between having smooth audio
playback in a separate thread but no visual feedback and having less
reliable audio playback in my UI thread with visual feedback?
Thanks again,
Nick Zaillian

On Aug 30, 4:13 pm, Romain Guy <[email protected]> wrote:
> You should call setBackgroundResource() but NOT from onDraw(). Just
> call this method from setIlluminated() for instance.
>
>
>
> On Sun, Aug 30, 2009 at 1:06 PM, Nick_Zaillian<[email protected]> wrote:
>
> > Mark and Romain,
> > Thanks.  That was a much prompter response than I either expected or
> > deserved.
> > Romain, I am not sure that I totally understand what you've said.  How
> > am I to set the background in accordance with the state of isChecked
> > and isIlluminated from within onDraw if not by calling
> > setBackgroundResource()?  I guess this post probably belongs in the
> > Android Beginner's group.
> > Thanks,
> > Nick Zaillian
>
> > On Aug 30, 2:59 pm, Romain Guy <[email protected]> wrote:
> >> Do not call setBacgroundResource() in onDraw()! You are loading and
> >> setting an image every time your view is drawn. You are actually
> >> creating a infinite "loop";
>
> >> onDraw() -> setBacgroundResource() -> invalidate() -> onDraw() ->
> >> setBacgroundResource() -> etc.
>
> >> On Sun, Aug 30, 2009 at 11:47 AM, Nick_Zaillian<[email protected]> wrote:
>
> >> > Hey all,
> >> > I am writing an app that emulates a drum machine with a step
> >> > sequencer.  For those unfamiliar with step sequencers, a step
> >> > sequencer is basically a set of switches where the state of each
> >> > switch indicates whether or not a sound is to be played at a
> >> > particular point in a pattern.  I've already got audio playback
> >> > working using SoundPool and can play patterns (represented as objects
> >> > containing boolean arrays mapped to audio resources) by stepping
> >> > through these patterns using a timer.  What I am trying and struggling
> >> > to do at present is to write my UI.  I have subclassed ToggleSwitch
> >> > and made a custom switch called SeqSwitch which, in addition to
> >> > ToggleSwitch's isChecked field, also holds an isIlluminated field.
> >> > I've written another class called SwitchController that takes an array
> >> > of these switches and has a method (which I've called runSwitches)
> >> > that, with each call, advances one switch, illuminates the current
> >> > switch, and unilluminates the previous switch (the idea is that, when
> >> > the user plays his pattern, the button representing the current step
> >> > will illuminate, letting him know the current position of playback in
> >> > the sequence).  The SeqSwitches seem to render and behave fine in
> >> > response to clicks.  My SwitchController.runSwitches method also works
> >> > so long as I place it in a click handler of a button in my main
> >> > Activity.  When, however, I pass it into the runnable (called
> >> > PatternPlayTask) that I give to my Timer (which then calls
> >> > SwitchController.runSwitches every 300 milliseconds as it steps
> >> > through the pattern), it stops working.  I have used the debugger to
> >> > make sure that the object I am passing into the runnable is the same
> >> > as the one for which the call to SwitchController.runSwitches was
> >> > working in the main activity and have found that definitely it is.
> >> > Does anybody have any idea what's going on here.  Hopefully I am just
> >> > doing something totally stupid, here.  I've pasted the code for my
> >> > ToggleButton subclass below, if that helps:
>
> >> > package com.drummachine;
> >> > import android.widget.*;
> >> > import android.view.*;
> >> > import android.content.Context;
> >> > import com.drummachine.Instrument;
> >> > import android.util.*;
> >> > import android.content.res.TypedArray;
> >> > import android.graphics.Canvas;
> >> > import android.graphics.Paint;
> >> > import android.graphics.drawable.*;
> >> > import android.util.AttributeSet;
> >> > import android.view.View;
>
> >> > public class SeqSwitch extends ToggleButton {
>
> >> >        //SeqSwitch holds an isIlluminated state.
> >> >        //if isIlluminated is true, onDraw will render an illuminated
> >> >        //button image as the SeqSwitch's drawable (currently the same 
> >> > image
> >> > used for
> >> >        //a ToggleButton whose isChecked == true)
> >> >        public boolean isIlluminated;
>
> >> >        public SeqSwitch(Context context)
> >> >        {
> >> >                super(context);
> >> >                isIlluminated = false;
>
> >> >        }
>
> >> >        //constructor called when params are taken from XML layout
> >> >    public SeqSwitch(Context context, AttributeSet attributes) {
> >> >        super(context, attributes);
>
> >> >        TypedArray a = context.obtainStyledAttributes(attributes,
> >> >                R.styleable.SeqSwitch);
>
> >> >       isIlluminated = false;
> >> >       super.setBackgroundResource
> >> > (R.drawable.seqswitchbackgroundsoneoff);
>
> >> >        a.recycle();
> >> >    }
>
> >> >    public void setIlluminated(boolean state)
> >> >    {
> >> >        isIlluminated = state;
> >> >        this.invalidate();
>
> >> >    }
>
> >> >    //yes, I know having illumniate() and unIlluminate() methods is
> >> > redundant
> >> >    //when I have a setIlluminated(boolean) method, but I am presently
> >> > too lazy
> >> >    //to rearrange code elsewhere that presently relies on these two
> >> > methods.
> >> >    public void unIlluminate()
> >> >    {
> >> >        isIlluminated = false;
> >> >        this.invalidate();
> >> >    }
>
> >> >    public void illuminate()
> >> >    {
> >> >        isIlluminated = true;
> >> >        this.invalidate();
> >> >    }
>
> >> >    public boolean switchIsIlluminated()
> >> >    {
> >> >        return isIlluminated;
> >> >    }
>
> >> >    /**
> >> >     * renders a image of a switch with an illuminated LED if either
> >> > the SeqSwitch's isChecked or
> >> >     * isIllumniated == true.  Otherwise it renders a drawable of a
> >> > button with an unIlluminated LED
> >> >     */
> >> >    public void onDraw(Canvas canvas)
> >> >    {
> >> >        if(super.isChecked() == true || this.isIlluminated == true)
> >> >        {
> >> >                super.setBackgroundResource
> >> > (R.drawable.seqswitchbackgroundsoneonon);
> >> >        }
> >> >        else
> >> >        {
> >> >                super.setBackgroundResource
> >> > (R.drawable.seqswitchbackgroundsoneoff);
> >> >        }
>
> >> >    }
> >> > }
>
> >> > Thanks,
> >> > Nick Zaillian
>
> >> --
> >> Romain Guy
> >> Android framework engineer
> >> [email protected]
>
> >> Note: please don't send private questions to me, as I don't have time
> >> to provide private support.  All such questions should be posted on
> >> public forums, where I and others can see and answer them
>
> --
> Romain Guy
> Android framework engineer
> [email protected]
>
> Note: please don't send private questions to me, as I don't have time
> to provide private support.  All such questions should be posted on
> public forums, where I and others can see and answer them
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to