2012-03-28 85 views
0

我想用android做一些繪圖。我有一臺audioplayer,它從服務器獲取波形圖。我想畫出這張照片。 (不要鏈接我的可視化例子,這不是我所期待的)。我發現這個教程(http://www.droidnova.com/playing-with-graphics-in-android-part-i,147.html),和我做了這個 我查看的子類:android ImageView子類不能正常顯示

public class WaveFormSurfaceView extends View { 

Bitmap waveform = null; 

public WaveFormSurfaceView(Context context) { 
    super(context); 

} 

public WaveFormSurfaceView(Context context, AttributeSet attrs){ 
    super(context,attrs); 
} 

public WaveFormSurfaceView(Context context, AttributeSet attrs, int defStyle){ 
    super(context,attrs,defStyle); 
} 

//copies the given waveform to a variable 
public void setWaveForm(Bitmap b) { 

    waveform = Bitmap.createBitmap(b.getWidth(), 
      b.getHeight(), b.getConfig()); 
    // copy the pixel to it 
    int[] allpixels = new int[b.getHeight() * b.getWidth()]; 
    b.getPixels(allpixels, 0, b.getWidth(), 0, 0, 
      b.getWidth(), b.getHeight()); 
    waveform.setPixels(allpixels, 0, b.getWidth(), 0, 0, 
      b.getWidth(), b.getHeight()); 


} 

@Override 
protected void onDraw(Canvas canvas) { 
    // TODO Auto-generated method stub 
    //super.onDraw(canvas); 

    // Create a paint object for us to draw with, and set our drawing color 
    // to blue. 
    Paint paint = new Paint(); 
    paint.setColor(Color.RED); 
    paint.setAlpha(50); 

    // draws the rectangle 

    if(waveform!=null){ 
    canvas.drawRect(0, 0, (float)0.5 * waveform.getWidth(), 
      waveform.getHeight(), paint); 
    }else{ 
     canvas.drawRect(0, 0,50, 
       50, paint); 
    } 
    //mImageView.setImageBitmap(map); 
} 

} 

這裏是我的活動:

public class AudioPlayerActivity extends Activity{ 
// Hardcoded parameters for the Verba demo server 
    private static final String ServerURL = "http://something.com"; 
    private static final String MediaPath = "C:\\path\\media\\"; 

    // Player user interface elements 
    private Button mBtnPlay; 
    private WaveFormSurfaceView mImageView; 

    //private ImageView mImageView; 
    private SeekBar mSeekBar; 
    private TextView mCurrentPos; 
    private TextView mEndPos; 

    private Bitmap originalWaveForm; 





    // THIS IS THE MEDIAPLAYER (has no UI, only loads and plays the audio) 
    private MediaPlayer mMediaPlayer; 

    // HTTP URL for the audio waveform PNG picture 
    private String getWaveformURL(String pCallURL) { 
     return ServerURL + ":8089/a?" + MediaPath + pCallURL 
       + "?1000020024024024"; 
    } 

    // HTTP URL for the audio transcoded to MP3 format 
    private String getMediaURL(String pCallURL) { 
     return ServerURL + ":10100/getMedia?file=" + MediaPath + pCallURL 
       + "&format=mp3"; 
    } 

    // Downloads the waveform image outside of the main GU thread 
    private class DownloadWaveformTask extends AsyncTask<String, Void, Bitmap> { 

     @Override 
     protected Bitmap doInBackground(String... urls) { 
      try { 
       return BitmapFactory.decodeStream((InputStream) new URL(
         getWaveformURL(myCallURL)) 
         .getContent()); 
      } catch (MalformedURLException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Bitmap result) { 
      //mImageView.setImageBitmap(result); 
      //setWaveForm(result); 
      mImageView.setWaveForm(result); 
     } 
    } 



    // Updates the seekbar outside of the main GU thread, started only after 
    // MediaPlayer exists 
    private class SeekBarUpdater extends Thread { 
     float p=0; 
     @Override 
     public void run() { 
      final SimpleDateFormat tf = new SimpleDateFormat("mm:ss.SSS"); 
      final Calendar calendar = Calendar.getInstance(); 

      int currentPosition = 0; 
      final int total = mMediaPlayer.getDuration(); // //returns in msec, 
                  // final because we 
                  // will use in the 
                  // runnable 

      // UI update must happen on the UI thread, so we post our actions 
      // there in a runnable 
      mCurrentPos.post(new Runnable() { 
       public void run() { 
        calendar.setTimeInMillis(total); 
        mEndPos.setText(tf.format(calendar.getTime())); 
        mSeekBar.setMax(total); 
       } 
      }); 

      while (mMediaPlayer != null && currentPosition < total) { 
       try { 
        Thread.sleep(50); 
        currentPosition = mMediaPlayer.getCurrentPosition(); // returns 
                      // in 
                      // msec 
       } catch (InterruptedException e) { 
        return; 
       } catch (Exception e) { 
        return; 
       } 

       // we are roughly adjusting for delays due to the thread 
       // communication 
       // currentPosition -= 100; 
       // if (currentPosition < 0) currentPosition = 0; 
       final int currPosition = currentPosition; // final because we 
                  // will use in the 
                  // runnable 

       p=(float)currentPosition/(float)total; 

       // UI update must happen on the UI thread, so we post our 
       // actions there in a runnable 
       mCurrentPos.post(new Runnable() { 
        public void run() { 
         calendar.setTimeInMillis(currPosition); 
         mCurrentPos.setText(tf.format(calendar.getTime())); 
         mSeekBar.setProgress(currPosition); 
         System.out.println("pecent="+p); 
         drawRectOnWaveForm(p); 
        } 
       }); 

      } 
     } 
    } 




    String myCallURL; 

    /** 
    * Create a new instance of MyFragment that will be initialized 
    * with the given arguments. 
    */ 
    static MediaPlayerFragment newInstance(CharSequence url) { 
     MediaPlayerFragment f = new MediaPlayerFragment(); 
     Bundle args = new Bundle(); 
     args.putCharSequence("call_url", url); 
     f.setArguments(args); 
     return f; 
    } 

    /** 
    * During creation, if arguments have been supplied to the fragment 
    * then parse those out. 
    */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     Bundle extras = getIntent().getExtras(); 
     if (extras != null) { 
      String value1 = extras.getString("call_url"); 
      if(value1!=null){ 
       myCallURL=value1; 
      } 
     } 



     setContentView(R.layout.mediaplayer); 
     System.out.println("AudioPlayerActivity setContentView, mycallurl: "+myCallURL); 

     DownloadWaveformTask task = new DownloadWaveformTask(); 
     task.execute(); 

     // part of the player UI 
     //mImageView = (ImageView) findViewById(R.id.imageView); 
     mImageView = (WaveFormSurfaceView) findViewById(R.id.imageView); 
     mBtnPlay = (Button) findViewById(R.id.playButton); 
     mSeekBar = (SeekBar) findViewById(R.id.seekBar); 
     mCurrentPos = (TextView) findViewById(R.id.currentPos); 
     mEndPos = (TextView) findViewById(R.id.endPos); 
     Button drawButton=(Button) findViewById(R.id.button1); 





     // 
     mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 

      @Override 
      public void onStopTrackingTouch(SeekBar seekBar) { 
      } 

      @Override 
      public void onStartTrackingTouch(SeekBar seekBar) { 
      } 

      @Override 
      public void onProgressChanged(SeekBar seekBar, int progress, 
        boolean fromUser) { 
       if (fromUser) { 
        // we only update the player if the change comes from a user 
        // action 
        mMediaPlayer.seekTo(progress); 
       } 
      } 
     }); 

     // IMPORTANT 
     // - The DownloadWaveformTask part should go into the initialization of 
     // the player fragment 
     // - currently we are NOT handling currently the end of playback 
     // situations, we should 
     // - currently we are NOT releasing the MediaPlayer resource, we should 
     // when a fragment closes 
     mBtnPlay.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       if (mMediaPlayer != null) { 
        if (mMediaPlayer.isPlaying()) { 
         mMediaPlayer.pause(); 
         mBtnPlay.setText("Play"); 
        } else { 
         mMediaPlayer.start(); 
         mBtnPlay.setText("Pause"); 
        } 
       } else { 


        mMediaPlayer = new MediaPlayer(); 
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 

        // this updates the seekbar as the buffering happens 
        mMediaPlayer 
          .setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { 

           @Override 
           public void onBufferingUpdate(MediaPlayer mp, 
             int percent) { 
            // TODO Auto-generated method stub 
            mSeekBar.setSecondaryProgress((int) (mSeekBar 
              .getMax() * percent/100)); 
           } 
          }); 

        try { 
         final String lMediaURL = getMediaURL(myCallURL); 
         mMediaPlayer.setDataSource(lMediaURL); 
         mMediaPlayer.prepare(); // might take long! (for 
               // buffering, etc) 
        } catch (IllegalArgumentException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } catch (IllegalStateException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
        mMediaPlayer.start(); 
        mBtnPlay.setText("Pause"); 

        // we start the thread that updates the seekbar, based on 
        // the state of the player 
        SeekBarUpdater thread = new SeekBarUpdater(); 
        thread.start(); 
       } 
      } 
     }); 

     // Close button 
     Button closeBtn = (Button) findViewById(R.id.closebtn); 
     closeBtn.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       //TODO ha megy a lejátszás, megállítjuk 
       if(mMediaPlayer!=null){ 
        if(mMediaPlayer.isPlaying()){ 
         mMediaPlayer.stop(); 
        } 
       } 
       finish(); 
      } 

     }); 
     //myCallURL = getArguments().getString("call_url"); 
     //myCallURL = savedInstanceState.getString("call_url"); 

     //int style = DialogFragment.STYLE_NORMAL; 
     //int theme = android.R.style.Theme_Dialog; 
     //setStyle(style, theme); 

    } 

} 

這裏是mediaplayer.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" 
android:gravity="center" 
> 

<TableLayout 
    android:id="@+id/tableLayout1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 

    > 

    <TableRow 
     android:id="@+id/tableRow1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:gravity="center" > 

     <adam.czibere.WaveFormSurfaceView 
      android:id="@+id/imageView" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      /> 

    </TableRow> 

    <TableRow 
     android:id="@+id/tableRow2" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" > 

     <SeekBar 
      android:id="@+id/seekBar" 
      android:layout_width="match_parent" 
      android:layout_weight="1" 
      android:layout_height="20dp" 
      android:layout_gravity="center" 
      android:thumb="@drawable/progress_fill" /> 

    </TableRow> 


    <TableRow 
     android:id="@+id/tableRow3" 
     android:layout_width="wrap_content" 
     android:layout_height="fill_parent" > 

     <TextView 
      android:id="@+id/currentPos" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:gravity="right" 
      android:layout_weight="5" 
      android:text="00:00.000" /> 

     <TextView 
      android:id="@+id/textView4" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:gravity="center_horizontal" 
      android:layout_weight="1" 
      android:text="/" /> 

     <TextView 
      android:id="@+id/endPos" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_weight="5" 
      android:gravity="left" 
      android:text="00:00.000" /> 
    </TableRow> 


    <TableRow 
     android:id="@+id/tableRow4" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" > 

     <Button 
      android:id="@+id/playButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:text="Play" /> 

     <Button 
      android:id="@+id/closebtn" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:text="Close" /> 

     <Button 
      android:id="@+id/button1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Button" 
      android:layout_weight="1" /> 

    </TableRow> 

</TableLayout> 

這是我得到的圖像http://i.stack.imgur.com/HULyi.png

我的問題是,所有其他小部件在哪裏?按鈕等?如果我正確地得到它,當我膨脹佈局時,波形圖像不是downloada呢?下載時如何畫出它?

回答

0

覆蓋WaveFormSurfaceView中的onMeasure()。

+0

我不知道你的應用程序的邏輯,我認爲你可以調用invalidate()來重繪視圖。 – 2012-03-28 13:57:15