/** * Makes the SlideView working on MMSConformance Mode. The view will be re-layout to the linear * view. * * <p>This is Chinese requirement about mms conformance. The most popular Mms service in China is * newspaper which is MMS conformance, normally it mixes the image and text and has a number of * slides. The AbsoluteLayout doesn't have good user experience for this kind of message, for * example, * * <p>1. AbsoluteLayout exactly follows the smil's layout which is not optimized, and actually, no * other MMS applications follow the smil's layout, they adjust the layout according their screen * size. MMS conformance doc also allows the implementation to adjust the layout. * * <p>2. The TextView is fixed in the small area of screen, and other part of screen is empty once * there is no image in the current slide. * * <p>3. The TextView is scrollable in a small area of screen and the font size is small which * make the user experience bad. * * <p>The better UI for the MMS conformance message could be putting the image/video and text in a * linear layout view and making them scrollable together. * * <p>Another reason for only applying the LinearLayout to the MMS conformance message is that the * AbsoluteLayout has ability to play image and video in a same screen. which shouldn't be broken. */ public void enableMMSConformanceMode(int textLeft, int textTop, int imageLeft, int imageTop) { mConformanceMode = true; if (mScrollViewPort == null) { mScrollViewPort = new ScrollView(mContext) { private int mBottomY; @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (getChildCount() > 0) { int childHeight = getChildAt(0).getHeight(); int height = getHeight(); mBottomY = height < childHeight ? childHeight - height : 0; } } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { // Shows MediaController when the view is scrolled to the top/bottom of itself. if (t == 0 || t >= mBottomY) { if (mMediaController != null) { mMediaController.show(); } } } }; mScrollViewPort.setScrollBarStyle(SCROLLBARS_OUTSIDE_INSET); mViewPort = new LinearLayout(mContext); mViewPort.setOrientation(LinearLayout.VERTICAL); mViewPort.setGravity(Gravity.CENTER); mViewPort.setOnClickListener( new OnClickListener() { public void onClick(View v) { if (mMediaController != null) { mMediaController.show(); } } }); mScrollViewPort.addView( mViewPort, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); addView(mScrollViewPort); } // Layout views to fit the LinearLayout from left to right, then top to // bottom. TreeMap<Position, View> viewsByPosition = new TreeMap<Position, View>( new Comparator<Position>() { public int compare(Position p1, Position p2) { int l1 = p1.mLeft; int t1 = p1.mTop; int l2 = p2.mLeft; int t2 = p2.mTop; int res = t1 - t2; if (res == 0) { res = l1 - l2; } if (res == 0) { // A view will be lost if return 0. return -1; } return res; } }); if (textLeft >= 0 && textTop >= 0) { mTextView = new TextView(mContext); mTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); mTextView.setTextSize(18); mTextView.setPadding(5, 5, 5, 5); viewsByPosition.put(new Position(textLeft, textTop), mTextView); } if (imageLeft >= 0 && imageTop >= 0) { mImageView = new ImageView(mContext); mImageView.setPadding(0, 5, 0, 5); viewsByPosition.put(new Position(imageLeft, imageTop), mImageView); // According MMS Conformance Document, the image and video should use the same // region. So, put the VideoView below the ImageView. mVideoView = new VideoView(mContext); viewsByPosition.put(new Position(imageLeft + 1, imageTop), mVideoView); } for (View view : viewsByPosition.values()) { if (view instanceof VideoView) { mViewPort.addView( view, new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutManager.getInstance().getLayoutParameters().getHeight())); } else { mViewPort.addView( view, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); } view.setVisibility(View.GONE); } }
public static SlideshowModel createFromPduBody(Context context, PduBody pb) throws MmsException { SMILDocument document = SmilHelper.getDocument(pb); // Create root-layout model. SMILLayoutElement sle = document.getLayout(); SMILRootLayoutElement srle = sle.getRootLayout(); int w = srle.getWidth(); int h = srle.getHeight(); if ((w == 0) || (h == 0)) { w = LayoutManager.getInstance().getLayoutParameters().getWidth(); h = LayoutManager.getInstance().getLayoutParameters().getHeight(); srle.setWidth(w); srle.setHeight(h); } RegionModel rootLayout = new RegionModel(null, 0, 0, w, h); // Create region models. ArrayList<RegionModel> regions = new ArrayList<RegionModel>(); NodeList nlRegions = sle.getRegions(); int regionsNum = nlRegions.getLength(); for (int i = 0; i < regionsNum; i++) { SMILRegionElement sre = (SMILRegionElement) nlRegions.item(i); RegionModel r = new RegionModel( sre.getId(), sre.getFit(), sre.getLeft(), sre.getTop(), sre.getWidth(), sre.getHeight(), sre.getBackgroundColor()); regions.add(r); } LayoutModel layouts = new LayoutModel(rootLayout, regions); // Create slide models. SMILElement docBody = document.getBody(); NodeList slideNodes = docBody.getChildNodes(); int slidesNum = slideNodes.getLength(); ArrayList<SlideModel> slides = new ArrayList<SlideModel>(slidesNum); for (int i = 0; i < slidesNum; i++) { // FIXME: This is NOT compatible with the SMILDocument which is // generated by some other mobile phones. SMILParElement par = (SMILParElement) slideNodes.item(i); // Create media models for each slide. NodeList mediaNodes = par.getChildNodes(); int mediaNum = mediaNodes.getLength(); ArrayList<MediaModel> mediaSet = new ArrayList<MediaModel>(mediaNum); for (int j = 0; j < mediaNum; j++) { SMILMediaElement sme = (SMILMediaElement) mediaNodes.item(j); try { MediaModel media = MediaModelFactory.getMediaModel(context, sme, layouts, pb); SmilHelper.addMediaElementEventListeners((EventTarget) sme, media); mediaSet.add(media); } catch (DrmException e) { Log.e(TAG, e.getMessage(), e); } catch (IOException e) { Log.e(TAG, e.getMessage(), e); } catch (IllegalArgumentException e) { Log.e(TAG, e.getMessage(), e); } } SlideModel slide = new SlideModel((int) (par.getDur() * 1000), mediaSet); slide.setFill(par.getFill()); SmilHelper.addParElementEventListeners((EventTarget) par, slide); slides.add(slide); } SlideshowModel slideshow = new SlideshowModel(layouts, slides, document, pb, context.getContentResolver()); slideshow.registerModelChangedObserver(slideshow); return slideshow; }