2012-01-11 78 views
2

我有一张从我​​的SD卡上拍摄的照相机的位图。我创建了一个视图组,我将其设置为我的活动视图。我想以编程方式创建视图,并将位图设置为视图,然后将视图添加到视图组并显示。一切似乎都起作用,而不是显示位图而不是黑屏。我已经检查过位图是否为空,并且视图组的子计数不为零。谢谢亚光如何将视图添加到视图组?

@Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      requestWindowFeature(Window.FEATURE_NO_TITLE); 
      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
        WindowManager.LayoutParams.FLAG_FULLSCREEN); 

      setContentView(R.layout.hpview); 
      final ViewGroup viewgroup = (ViewGroup)findViewById(R.id.hpview); 






      tempFile = new File(Environment.getExternalStorageDirectory(). 
        getAbsolutePath() + "/"+"image.jpeg"); 

      imageArray = new byte[(int)tempFile.length()]; 





     try{ 

       InputStream is = new FileInputStream(tempFile); 
       BufferedInputStream bis = new BufferedInputStream(is); 
       DataInputStream dis = new DataInputStream(bis); 


       int i = 0; 

       while (dis.available() > 0) { 
       imageArray[i] = dis.readByte(); 
       i++; 
       } 

       dis.close(); 


      } catch (Exception e) { 

        e.printStackTrace(); 
       } 



      Bitmap bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length); 

      if(bm == null){ 
       Log.e(TAG, "bm = null"); 
      }else{ 
       Log.e(TAG, "bm = not null"); 
      } 




      Paint pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);   

      Canvas canvas = new Canvas(); 
      Log.e(TAG, "canvas created"); 

      canvas.drawBitmap(bm, 10, 10, pTouch); 
      Log.e(TAG, "canvas drawn bm"); 

      View view = new View(this); 
      Log.e(TAG, "view created"); 


      viewgroup.addView(view); 
      Log.e(TAG, "view added to viewgroup"); 

      viewgroup.bringChildToFront(view); 
      viewgroup.postInvalidate(); 
      Log.e(TAG, "post inval called on viewgroup"); 

      Log.e(TAG, "no of chidren = "+viewgroup.getChildCount()); 

    } 

01-11 12:35:03.747: ERROR/*********entryscreen(5179): clicked slide 
01-11 12:35:03.747: INFO/ActivityManager(1900): Starting activity: Intent { cmp=com.tecmark/.HorizontalPagerActivity } 
01-11 12:35:03.767: ERROR/*********horizontalpager(5179): inside hp constructor for xml inflation 
01-11 12:35:03.772: INFO/global(5179): Default buffer size used in BufferedInputStream constructor. It would be better to be explicit if an 8k buffer is required. 
01-11 12:35:03.952: DEBUG/dalvikvm(5179): GC freed 1172 objects/92200 bytes in 65ms 
01-11 12:35:03.982: ERROR/*********hpActivity(5179): bm = not null 
01-11 12:35:03.982: ERROR/*********hpActivity(5179): canvas created 
01-11 12:35:03.982: ERROR/*********hpActivity(5179): canvas drawn bm 
01-11 12:35:03.982: ERROR/*********hpActivity(5179): view created 
01-11 12:35:03.982: ERROR/*********hpActivity(5179): view added to viewgroup 
01-11 12:35:03.982: ERROR/*********hpActivity(5179): post inval called on viewgroup 
01-11 12:35:03.982: ERROR/*********hpActivity(5179): no of chidren = 1 

[编辑]

/** 
* A view group that allows users to switch between multiple screens (layouts) in the same way as 
* the Android home screen (Launcher application). 
* <p> 
* You can add and remove views using the normal methods {@link ViewGroup#addView(View)}, 
* {@link ViewGroup#removeView(View)} etc. You may want to listen for updates by calling 
* {@link HorizontalPager#setOnScreenSwitchListener(OnScreenSwitchListener)} in order to perform 
* operations once a new screen has been selected. 
* 
* Modifications from original version (ysamlan): Animate argument in setCurrentScreen and duration 
* in snapToScreen; onInterceptTouchEvent handling to support nesting a vertical Scrollview inside 
* the RealViewSwitcher; allowing snapping to a view even during an ongoing scroll; snap to 
* next/prev view on 25% scroll change; density-independent swipe sensitivity; width-independent 
* pager animation durations on scrolling to properly handle large screens without excessively 
* long animations. 
* 
* Other modifications: 
* (aveyD) Handle orientation changes properly and fully snap to the right position. 
* 
* @author Marc Reichelt, <a href="http://www.marcreichelt.de/">http://www.marcreichelt.de/</a> 
* @version 0.1.0 
*/ 
public final class HorizontalPager extends ViewGroup { 
    /* 
    * How long to animate between screens when programmatically setting with setCurrentScreen using 
    * the animate parameter 
    */ 
    private static final int ANIMATION_SCREEN_SET_DURATION_MILLIS = 500; 
    // What fraction (1/x) of the screen the user must swipe to indicate a page change 
    private static final int FRACTION_OF_SCREEN_WIDTH_FOR_SWIPE = 4; 
    private static final int INVALID_SCREEN = -1; 
    /* 
    * Velocity of a swipe (in density-independent pixels per second) to force a swipe to the 
    * next/previous screen. Adjusted into mDensityAdjustedSnapVelocity on init. 
    */ 
    private static final int SNAP_VELOCITY_DIP_PER_SECOND = 600; 
    // Argument to getVelocity for units to give pixels per second (1 = pixels per millisecond). 
    private static final int VELOCITY_UNIT_PIXELS_PER_SECOND = 1000; 

    private static final int TOUCH_STATE_REST = 0; 
    private static final int TOUCH_STATE_HORIZONTAL_SCROLLING = 1; 
    private static final int TOUCH_STATE_VERTICAL_SCROLLING = -1; 
    private int mCurrentScreen; 
    private int mDensityAdjustedSnapVelocity; 
    private boolean mFirstLayout = true; 
    private float mLastMotionX; 
    private float mLastMotionY; 
    private OnScreenSwitchListener mOnScreenSwitchListener; 
    private int mMaximumVelocity; 
    private int mNextScreen = INVALID_SCREEN; 
    private Scroller mScroller; 
    private int mTouchSlop; 
    private int mTouchState = TOUCH_STATE_REST; 
    private VelocityTracker mVelocityTracker; 
    private int mLastSeenLayoutWidth = -1; 
    private static final String TAG = "*********horizontalpager"; 

    /** 
    * Simple constructor to use when creating a view from code. 
    * 
    * @param context The Context the view is running in, through which it can 
    *  access the current theme, resources, etc. 
    */ 
    public HorizontalPager(final Context context) { 
     super(context); 
     Log.e(TAG, "inside hp standard constructor"); 
     init(); 
    } 

    /** 
    * Constructor that is called when inflating a view from XML. This is called 
    * when a view is being constructed from an XML file, supplying attributes 
    * that were specified in the XML file. This version uses a default style of 
    * 0, so the only attribute values applied are those in the Context's Theme 
    * and the given AttributeSet. 
    * 
    * <p> 
    * The method onFinishInflate() will be called after all children have been 
    * added. 
    * 
    * @param context The Context the view is running in, through which it can 
    *  access the current theme, resources, etc. 
    * @param attrs The attributes of the XML tag that is inflating the view. 
    * @see #View(Context, AttributeSet, int) 
    */ 
    public HorizontalPager(final Context context, final AttributeSet attrs) { 
     super(context, attrs); 
     Log.e(TAG, "inside hp constructor for xml inflation"); 
     init(); 
    } 

    /** 
    * Sets up the scroller and touch/fling sensitivity parameters for the pager. 
    */ 
    private void init() { 
     mScroller = new Scroller(getContext()); 

     // Calculate the density-dependent snap velocity in pixels 
     DisplayMetrics displayMetrics = new DisplayMetrics(); 
     ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay() 
       .getMetrics(displayMetrics); 
     mDensityAdjustedSnapVelocity = 
       (int) (displayMetrics.density * SNAP_VELOCITY_DIP_PER_SECOND); 

     final ViewConfiguration configuration = ViewConfiguration.get(getContext()); 
     mTouchSlop = configuration.getScaledTouchSlop(); 
     mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); 
    } 

    @Override 
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     final int width = MeasureSpec.getSize(widthMeasureSpec); 
     final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
     if (widthMode != MeasureSpec.EXACTLY) { 
      throw new IllegalStateException("ViewSwitcher can only be used in EXACTLY mode."); 
     } 

     final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
     if (heightMode != MeasureSpec.EXACTLY) { 
      throw new IllegalStateException("ViewSwitcher can only be used in EXACTLY mode."); 
     } 

     // The children are given the same width and height as the workspace 
     final int count = getChildCount(); 
     for (int i = 0; i < count; i++) { 
      getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec); 
     } 

     if (mFirstLayout) { 
      scrollTo(mCurrentScreen * width, 0); 
      mFirstLayout = false; 
     } 

     else if (width != mLastSeenLayoutWidth) { // Width has changed 
      /* 
      * Recalculate the width and scroll to the right position to be sure we're in the right 
      * place in the event that we had a rotation that didn't result in an activity restart 
      * (code by aveyD). Without this you can end up between two pages after a rotation. 
      */ 
      Display display = 
        ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)) 
          .getDefaultDisplay(); 
      int displayWidth = display.getWidth(); 

      mNextScreen = Math.max(0, Math.min(getCurrentScreen(), getChildCount() - 1)); 
      final int newX = mNextScreen * displayWidth; 
      final int delta = newX - getScrollX(); 

      mScroller.startScroll(getScrollX(), 0, delta, 0, 0); 
     } 

     mLastSeenLayoutWidth = width; 
    } 

    @Override 
    protected void onLayout(final boolean changed, final int l, final int t, final int r, 
      final int b) { 
     int childLeft = 0; 
     final int count = getChildCount(); 

     for (int i = 0; i < count; i++) { 
      final View child = getChildAt(i); 
      if (child.getVisibility() != View.GONE) { 
       final int childWidth = child.getMeasuredWidth(); 
       child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight()); 
       childLeft += childWidth; 
      } 
     } 
    } 

    @Override 
    public boolean onInterceptTouchEvent(final MotionEvent ev) { 
     /* 
     * By Yoni Samlan: Modified onInterceptTouchEvent based on standard ScrollView's 
     * onIntercept. The logic is designed to support a nested vertically scrolling view inside 
     * this one; once a scroll registers for X-wise scrolling, handle it in this view and don't 
     * let the children, but once a scroll registers for y-wise scrolling, let the children 
     * handle it exclusively. 
     */ 
     final int action = ev.getAction(); 
     boolean intercept = false; 

     switch (action) { 
      case MotionEvent.ACTION_MOVE: 
       /* 
       * If we're in a horizontal scroll event, take it (intercept further events). But if 
       * we're mid-vertical-scroll, don't even try; let the children deal with it. If we 
       * haven't found a scroll event yet, check for one. 
       */ 
       if (mTouchState == TOUCH_STATE_HORIZONTAL_SCROLLING) { 
        /* 
        * We've already started a horizontal scroll; set intercept to true so we can 
        * take the remainder of all touch events in onTouchEvent. 
        */ 
        intercept = true; 
       } else if (mTouchState == TOUCH_STATE_VERTICAL_SCROLLING) { 
        // Let children handle the events for the duration of the scroll event. 
        intercept = false; 
       } else { // We haven't picked up a scroll event yet; check for one. 

        /* 
        * If we detected a horizontal scroll event, start stealing touch events (mark 
        * as scrolling). Otherwise, see if we had a vertical scroll event -- if so, let 
        * the children handle it and don't look to intercept again until the motion is 
        * done. 
        */ 

        final float x = ev.getX(); 
        final int xDiff = (int) Math.abs(x - mLastMotionX); 
        boolean xMoved = xDiff > mTouchSlop; 

        if (xMoved) { 
         // Scroll if the user moved far enough along the X axis 
         mTouchState = TOUCH_STATE_HORIZONTAL_SCROLLING; 
         mLastMotionX = x; 
        } 

        final float y = ev.getY(); 
        final int yDiff = (int) Math.abs(y - mLastMotionY); 
        boolean yMoved = yDiff > mTouchSlop; 

        if (yMoved) { 
         mTouchState = TOUCH_STATE_VERTICAL_SCROLLING; 
        } 
       } 

       break; 
      case MotionEvent.ACTION_CANCEL: 
      case MotionEvent.ACTION_UP: 
       // Release the drag. 
       mTouchState = TOUCH_STATE_REST; 
       break; 
      case MotionEvent.ACTION_DOWN: 
       /* 
       * No motion yet, but register the coordinates so we can check for intercept at the 
       * next MOVE event. 
       */ 
       mLastMotionY = ev.getY(); 
       mLastMotionX = ev.getX(); 
       break; 
      default: 
       break; 
      } 

     return intercept; 
    } 

    @Override 
    public boolean onTouchEvent(final MotionEvent ev) { 

     if (mVelocityTracker == null) { 
      mVelocityTracker = VelocityTracker.obtain(); 
     } 
     mVelocityTracker.addMovement(ev); 

     final int action = ev.getAction(); 
     final float x = ev.getX(); 

     switch (action) { 
      case MotionEvent.ACTION_DOWN: 
       /* 
       * If being flinged and user touches, stop the fling. isFinished will be false if 
       * being flinged. 
       */ 
       if (!mScroller.isFinished()) { 
        mScroller.abortAnimation(); 
       } 

       // Remember where the motion event started 
       mLastMotionX = x; 

       if (mScroller.isFinished()) { 
        mTouchState = TOUCH_STATE_REST; 
       } else { 
        mTouchState = TOUCH_STATE_HORIZONTAL_SCROLLING; 
       } 

       break; 
      case MotionEvent.ACTION_MOVE: 
       final int xDiff = (int) Math.abs(x - mLastMotionX); 
       boolean xMoved = xDiff > mTouchSlop; 

       if (xMoved) { 
        // Scroll if the user moved far enough along the X axis 
        mTouchState = TOUCH_STATE_HORIZONTAL_SCROLLING; 
       } 

       if (mTouchState == TOUCH_STATE_HORIZONTAL_SCROLLING) { 
        // Scroll to follow the motion event 
        final int deltaX = (int) (mLastMotionX - x); 
        mLastMotionX = x; 
        final int scrollX = getScrollX(); 

        if (deltaX < 0) { 
         if (scrollX > 0) { 
          scrollBy(Math.max(-scrollX, deltaX), 0); 
         } 
        } else if (deltaX > 0) { 
         final int availableToScroll = 
           getChildAt(getChildCount() - 1).getRight() - scrollX - getWidth(); 

         if (availableToScroll > 0) { 
          scrollBy(Math.min(availableToScroll, deltaX), 0); 
         } 
        } 
       } 

       break; 

      case MotionEvent.ACTION_UP: 
       if (mTouchState == TOUCH_STATE_HORIZONTAL_SCROLLING) { 
        final VelocityTracker velocityTracker = mVelocityTracker; 
        velocityTracker.computeCurrentVelocity(VELOCITY_UNIT_PIXELS_PER_SECOND, 
          mMaximumVelocity); 
        int velocityX = (int) velocityTracker.getXVelocity(); 

        if (velocityX > mDensityAdjustedSnapVelocity && mCurrentScreen > 0) { 
         // Fling hard enough to move left 
         snapToScreen(mCurrentScreen - 1); 
        } else if (velocityX < -mDensityAdjustedSnapVelocity 
          && mCurrentScreen < getChildCount() - 1) { 
         // Fling hard enough to move right 
         snapToScreen(mCurrentScreen + 1); 
        } else { 
         snapToDestination(); 
        } 

        if (mVelocityTracker != null) { 
         mVelocityTracker.recycle(); 
         mVelocityTracker = null; 
        } 
       } 

       mTouchState = TOUCH_STATE_REST; 

       break; 
      case MotionEvent.ACTION_CANCEL: 
       mTouchState = TOUCH_STATE_REST; 
       break; 
      default: 
       break; 
     } 

     return true; 
    } 

    @Override 
    public void computeScroll() { 
     if (mScroller.computeScrollOffset()) { 
      scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 
      postInvalidate(); 
     } else if (mNextScreen != INVALID_SCREEN) { 
      mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1)); 

      // Notify observer about screen change 
      if (mOnScreenSwitchListener != null) { 
       mOnScreenSwitchListener.onScreenSwitched(mCurrentScreen); 
      } 

      mNextScreen = INVALID_SCREEN; 
     } 
    } 

    /** 
    * Returns the index of the currently displayed screen. 
    * 
    * @return The index of the currently displayed screen. 
    */ 
    public int getCurrentScreen() { 
     return mCurrentScreen; 
    } 

    /** 
    * Sets the current screen. 
    * 
    * @param currentScreen The new screen. 
    * @param animate True to smoothly scroll to the screen, false to snap instantly 
    */ 
    public void setCurrentScreen(final int currentScreen, final boolean animate) { 
     mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1)); 
     if (animate) { 
      snapToScreen(currentScreen, ANIMATION_SCREEN_SET_DURATION_MILLIS); 
     } else { 
      scrollTo(mCurrentScreen * getWidth(), 0); 
     } 
     invalidate(); 
    } 

    /** 
    * Sets the {@link OnScreenSwitchListener}. 
    * 
    * @param onScreenSwitchListener The listener for switch events. 
    */ 
    public void setOnScreenSwitchListener(final OnScreenSwitchListener onScreenSwitchListener) { 
     mOnScreenSwitchListener = onScreenSwitchListener; 
    } 

    /** 
    * Snaps to the screen we think the user wants (the current screen for very small movements; the 
    * next/prev screen for bigger movements). 
    */ 
    private void snapToDestination() { 
     final int screenWidth = getWidth(); 
     int scrollX = getScrollX(); 
     int whichScreen = mCurrentScreen; 
     int deltaX = scrollX - (screenWidth * mCurrentScreen); 

     // Check if they want to go to the prev. screen 
     if ((deltaX < 0) && mCurrentScreen != 0 
       && ((screenWidth/FRACTION_OF_SCREEN_WIDTH_FOR_SWIPE) < -deltaX)) { 
      whichScreen--; 
      // Check if they want to go to the next screen 
     } else if ((deltaX > 0) && (mCurrentScreen + 1 != getChildCount()) 
       && ((screenWidth/FRACTION_OF_SCREEN_WIDTH_FOR_SWIPE) < deltaX)) { 
      whichScreen++; 
     } 

     snapToScreen(whichScreen); 
    } 

    /** 
    * Snap to a specific screen, animating automatically for a duration proportional to the 
    * distance left to scroll. 
    * 
    * @param whichScreen Screen to snap to 
    */ 
    private void snapToScreen(final int whichScreen) { 
     snapToScreen(whichScreen, -1); 
    } 

    /** 
    * Snaps to a specific screen, animating for a specific amount of time to get there. 
    * 
    * @param whichScreen Screen to snap to 
    * @param duration -1 to automatically time it based on scroll distance; a positive number to 
    *   make the scroll take an exact duration. 
    */ 
    private void snapToScreen(final int whichScreen, final int duration) { 
     /* 
     * Modified by Yoni Samlan: Allow new snapping even during an ongoing scroll animation. This 
     * is intended to make HorizontalPager work as expected when used in conjunction with a 
     * RadioGroup used as "tabbed" controls. Also, make the animation take a percentage of our 
     * normal animation time, depending how far they've already scrolled. 
     */ 
     mNextScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); 
     final int newX = mNextScreen * getWidth(); 
     final int delta = newX - getScrollX(); 

     if (duration < 0) { 
      // E.g. if they've scrolled 80% of the way, only animation for 20% of the duration 
      mScroller.startScroll(getScrollX(), 0, delta, 0, (int) (Math.abs(delta) 
        /(float) getWidth() * ANIMATION_SCREEN_SET_DURATION_MILLIS)); 
     } else { 
      mScroller.startScroll(getScrollX(), 0, delta, 0, duration); 
     } 

     invalidate(); 
    } 

    /** 
    * Listener for the event that the HorizontalPager switches to a new view. 
    */ 
    public static interface OnScreenSwitchListener { 
     /** 
     * Notifies listeners about the new screen. Runs after the animation completed. 
     * 
     * @param screen The new screen index. 
     */ 
     void onScreenSwitched(int screen); 
    } 

    @Override 
    public void onDraw(Canvas canvas){ 
     super.onDraw(canvas); 
     Log.e(TAG, "inside hp ondraw()"); 

    } 


} 

回答

0

尝试增加的LayoutParams到视图保持位图等

LayoutParams lp = new LayoutParams(LayoutParam.FILL_PARENT, 
     LayoutParam.FILL_PARENT); 
view.setLayoutParams(lp); 
+0

喜无差异我是affraid。我也添加了view.draw(canvas); – turtleboy 2012-01-11 12:54:40

+0

为什么不只是创建一个视图。并使用代码view.setBackgroundDrawable(new BitmapDrawable(bm)); – blessenm 2012-01-11 13:13:28

+0

我发现了可以制作幻灯片的代码,也许就像您网站上的代码一样;)它是一个在视图之间切换的视图组,我需要提供视图。谢谢 – turtleboy 2012-01-11 13:24:29