代码之家  ›  专栏  ›  技术社区  ›  krishank Tripathi

在为整个布局截图时,只有屏幕上可见的列表项以位图的形式出现

  •  0
  • krishank Tripathi  · 技术社区  · 7 年前

    我正在尝试拍摄整个视图的截图,并通过pdf或图像共享它。 这是我的布局视图。

    活动xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/mainView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/White"
        tools:context="com.tally.enjay.tallyandroid.activity.LedgerTransactionHistoryActivity">
    
        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />
    
        <RelativeLayout
            android:id="@+id/relativeLayout"
            style="@style/Base.CardView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/toolbar"
            android:background="@color/DateTheme"
            android:elevation="2dp"
            android:padding="10dp">
    
    
            <RelativeLayout
                android:id="@+id/relative_date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
    
                <TextView
                    android:id="@+id/current_date"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentStart="true"
                    android:layout_marginEnd="5dp"
                    android:text="01/04/17 - 31/03/18"
                    android:textColor="@color/Black"
                    android:textSize="14sp"
                    android:textStyle="bold"
                    tools:ignore="HardcodedText" />
    
                <TextView
                    android:id="@+id/vs"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentStart="true"
                    android:layout_below="@+id/current_date"
                    android:padding="2dp"
                    android:text="vs."
                    android:textColor="@color/colorGreyshred"
                    android:textSize="13sp"
                    android:visibility="gone"
                    tools:ignore="HardcodedText,RtlSymmetry" />
    
                <TextView
                    android:id="@+id/previous_date"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/current_date"
                    android:layout_marginStart="1dp"
                    android:layout_toEndOf="@+id/vs"
                    android:padding="2dp"
                    android:text="01/04/16 - 31/03/17"
                    android:textColor="@color/colorGreyshred"
                    android:textSize="13sp"
                    android:visibility="gone"
                    tools:ignore="HardcodedText" />
    
    
            </RelativeLayout>
    
        </RelativeLayout>
    
        <TextView
            android:id="@+id/amount"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/relativeLayout"
            android:layout_marginBottom="10dp"
            android:background="@color/DateTheme"
            android:gravity="center"
            android:padding="5dp"
            android:textColor="?attr/colorPrimary"
            android:textSize="18sp"
            android:textStyle="" />
    
        <RelativeLayout
            android:id="@+id/table_header"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/amount">
    
            <TextView
                android:id="@+id/header_date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="5dp"
                android:padding="5dp"
                android:text="Date"
                android:textSize="15sp"
                android:textStyle="bold" />
    
            <TextView
                android:id="@+id/header_vch"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="25dp"
                android:layout_toEndOf="@id/header_date"
                android:padding="5dp"
                android:text="Vch No. / Vch Type"
                android:textSize="15sp"
                android:textStyle="bold" />
    
            <TextView
                android:id="@+id/header_amt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:padding="5dp"
                android:paddingEnd="50dp"
                android:text="Amount"
                android:textSize="15sp"
                android:textStyle="bold" />
    
        </RelativeLayout>
    
        <FrameLayout
            android:id="@+id/empty_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:visibility="gone">
    
            <TextView
                android:id="@+id/ledger_empty_txt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="@string/no_data_available_for_this_ledger"
                android:textSize="15sp" />
    
        </FrameLayout>
    
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipe"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/table_header">
    
            <ListView
                android:id="@+id/list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/white" />
    
        </android.support.v4.widget.SwipeRefreshLayout>
    
    </RelativeLayout>
    

    现在,当我单击工具栏中的共享按钮时,它将打开弹出菜单来共享图像或pdf。关于图像或pdf的选择,我的方法是 shareViaPdfOrImage(字符串选择) 调用,其中选择将包含每个弹出菜单选项的PDF或图像aas字符串。

    活动班

         private void shareViaPdfOrImage(String selection) {
                Bitmap bitmap = takeScreenshot();   //method called to take screen shot here is think my issues is happening.
                saveBitmap(bitmap, selection);
    
            }
    
           //This whole method is woking fine so i am not expnading it.
            private void saveBitmap(Bitmap myBitmap, String selection) {
                final String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myappxyz";
    
                if (selection.equals("PDF")) {
                    createPdf(myBitmap, dirPath);
                } else if (selection.equals("Image")) {
                    createImage(myBitmap, dirPath);
                }
    
    
            }
    
     // My issues starts with this method
     private Bitmap takeScreenshot() {
            //View view = getWindow().findViewById(R.id.mainView);
            //  int width = view.getWidth();
            //  int height = view.getHeight();
            RelativeLayout mainView = findViewById(R.id.mainView);
            int childcount = mainView.getChildCount();
            Log.e("childCount", "==>" + childcount);
    
            ArrayList<Bitmap> bitmaps = new ArrayList<>();
            for (int i = 0; i < childcount; i++) {
    
                View subview = mainView.getChildAt(i);
    
                if (subview instanceof SwipeRefreshLayout) {
                    Log.e("subview is swipe", "==>" + i);
                    bitmaps.add(getWholeListViewItemsToBitmap(listView));
    
                } else {
                    bitmaps.add(Bitmap.createBitmap(subview.getWidth(), subview.getHeight(), Bitmap.Config.ARGB_8888));
                }
                //bitmaps.add(Bitmap.createBitmap(mainView.getChildAt(i).getWidth(), mainView.getChildAt(i).getHeight(), Bitmap.Config.ARGB_8888));
    
    
            }
    
    
    
            Bitmap tempbitmap = combineImageIntoOne(bitmaps, mainView);
    
            Bitmap bitmap = tempbitmap.copy(Bitmap.Config.ARGB_8888, true);
    
            Canvas canvas = new Canvas(bitmap);
            mainView.layout(0, 0, mainView.getLayoutParams().width, mainView.getLayoutParams().height);
            Drawable bgDrawable = mainView.getBackground();
            if (bgDrawable != null)
                bgDrawable.draw(canvas);
            else
                canvas.drawColor(Color.WHITE);
            mainView.draw(canvas);
            return bitmap;
        }
    
        private Bitmap combineImageIntoOne(ArrayList<Bitmap> bitmap, RelativeLayout mainView) {
            int w = 0, h = 0;
            for (int i = 0; i < bitmap.size(); i++) {
                if (i < bitmap.size() - 1) {
                    w = bitmap.get(i).getWidth() > bitmap.get(i + 1).getWidth() ? bitmap.get(i).getWidth() : bitmap.get(i + 1).getWidth();
                }
                h += bitmap.get(i).getHeight();
            }
    
            Bitmap temp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(temp);
            int top = 0;
            for (int i = 0; i < bitmap.size(); i++) {
                //Log.d("HTML", "Combine: "+i+"/"+bitmap.size()+1);
    
                top = (i == 0 ? 0 : top + bitmap.get(i).getHeight());
                canvas.drawBitmap(bitmap.get(i), 0f, top, null);
                // canvas.drawBitmap(bitmap.get(i), new Matrix(), null);
                //canvas.drawBitmap(bitmap.get(i+1), 0, 0, null);
            }
            //canvas.drawColor(Color.WHITE);
    
            return temp;
        }
    
      // This method will get all list items screen shot in one bitmap.
      public Bitmap getWholeListViewItemsToBitmap(ListView p_ListView) {
            ListView listview = p_ListView;
            ListAdapter adapter = listview.getAdapter();
            int itemscount = adapter.getCount();
            int allitemsheight = 0;
            List<Bitmap> bmps = new ArrayList<Bitmap>();
            for (int i = 0; i < itemscount; i++) {
                View childView = adapter.getView(i, null, listview);
                childView.measure(
                        View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());
                childView.setDrawingCacheEnabled(true);
                childView.buildDrawingCache();
                bmps.add(childView.getDrawingCache());
                allitemsheight += childView.getMeasuredHeight();
            }
            Bitmap bigbitmap = Bitmap.createBitmap(listview.getMeasuredWidth(), allitemsheight,
                    Bitmap.Config.ARGB_8888);
            Canvas bigcanvas = new Canvas(bigbitmap);
            //bigcanvas.drawColor(Color.WHITE);
    
            Paint paint = new Paint();
            int iHeight = 0;
            for (int i = 0; i < bmps.size(); i++) {
                Bitmap bmp = bmps.get(i);
                bigcanvas.drawBitmap(bmp, 0, iHeight, paint);
                iHeight += bmp.getHeight();
                bmp.recycle();
                bmp = null;
            }
            //Long tsLong = System.currentTimeMillis() / 1000;
    
    
            return storeImage(bigbitmap);
        }
    
        //This method will save bitmap and store it in app data and will return a bitmap to the mani method.
        public Bitmap storeImage(Bitmap imageData) {
            // get path to external storage (SD card)
            final String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myappxyz";
    
            File dir = new File(dirPath);
            if (!dir.exists())
                dir.mkdirs();
    
            String fileName = "LastSharedImage.jpg";
            File file = new File(dirPath, fileName);
            try {
                FileOutputStream fOut = new FileOutputStream(file);
                imageData.compress(Bitmap.CompressFormat.PNG, 85, fOut);
                fOut.flush();
                fOut.close();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
            Log.e("AbosolutePath","==>"+file.getAbsolutePath());
    
    
            return bitmap;
    
        }
    

    问题:: 我得到一个最终位图,并将其传递给创建pdf或图像,但最终的结果是,我的位图仅用于当前可见的视图,即使我使用getWholeListViewItemsToBitmap(ListView p\u ListView)方法获得整个列表视图屏幕截图,只需在其中传递一个ListView即可。目前,我得到了屏幕上10个可见项目的屏幕截图,以及相对主视图到相对表布局的布局,然后是一个很长的空白区域,我认为这是由于剩余的列表视图项目在屏幕上不可见,但在列表视图中,即使向下滚动到最后,也会发生这种情况。我尝试了所有方法,但都失败了。

    注:: 我在列表视图中有52个列表项,在屏幕截图中只有10-12个列表项可见,当前显示在列表视图中。

    要求 ::只需在android端解决此问题,不想使用任何第三方库。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Sachin Ahir    7 年前

    请检查下面的代码。

    private void shareViaPdfOrImage(String selection) {
            Bitmap bitmap = takeScreenshot();
            saveBitmap(bitmap, selection);
        }
    
        private void saveBitmap(Bitmap myBitmap, String selection) {
            final String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tallyandroid";
    
            if (selection.equals("PDF")) {
                createPdf(myBitmap, dirPath);
            } else if (selection.equals("Image")) {
                createImage(myBitmap, dirPath);
            }
        }
    
            WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            DisplayMetrics displaymetrics = new DisplayMetrics();
            this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
            float hight = displaymetrics.heightPixels;
            float width = displaymetrics.widthPixels;
    
            int convertHighet = (int) hight, convertWidth = (int) width;
    
    
            PdfDocument document = new PdfDocument();
            PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(myBitmap.getWidth(), myBitmap.getHeight(), 1).create();
            PdfDocument.Page page = document.startPage(pageInfo);
    
            Canvas canvas = page.getCanvas();
    
    
            Paint paint = new Paint();
            paint.setColor(Color.parseColor("#ffffff"));
            canvas.drawPaint(paint);
    
    
            myBitmap = Bitmap.createScaledBitmap(myBitmap, myBitmap.getWidth(), myBitmap.getHeight(), true);
    
            paint.setColor(Color.BLUE);
            canvas.drawBitmap(myBitmap, 0, 0, null);
            document.finishPage(page);
    
    
            // write the document content
            File dir = new File(dirPath);
            if (!dir.exists())
                dir.mkdirs();
          // Long tsLong = System.currentTimeMillis() / 1000;
    
            String fileName = "LastImageShared.pdf";
            File filePath = new File(dirPath, fileName);
            try {
                document.writeTo(new FileOutputStream(filePath));
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(this, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
            }
    
            // close the document
            document.close();
    
            //sending broadcast to the system file manager
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                final Uri contentUri = Uri.fromFile(filePath);
                scanIntent.setData(contentUri);
                sendBroadcast(scanIntent);
            } else {
                final Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()));
                sendBroadcast(intent);
            }
    
            File outputFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/tallyandroid", fileName);
            sharePdf(outputFile);
        }
        private void shareImg(File dir) {
            try {
                Uri uri = FileProvider.getUriForFile(LedgerTransactionHistoryActivity.this, LedgerTransactionHistoryActivity.this.getApplicationContext().getPackageName() + ".provider", dir);
                Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
                sharingIntent.setType("image/*");
                sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
                startActivity(Intent.createChooser(sharingIntent, "Share via"));
            } catch (Exception e) {
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
    
        }
    
        private void sharePdf(File dir) {
            try {
                progress_dialog.dismiss();
                Uri uri = FileProvider.getUriForFile(LedgerTransactionHistoryActivity.this, LedgerTransactionHistoryActivity.this.getApplicationContext().getPackageName() + ".provider", dir);
                Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
                sharingIntent.setType("application/pdf");
                sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
                startActivity(Intent.createChooser(sharingIntent, "Share via"));
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    
        private Bitmap takeScreenshot() {
    
            RelativeLayout mainView = findViewById(R.id.mainView);
            int childcount = mainView.getChildCount();
            Log.e("childCount", "==>" + childcount);
            ArrayList<Bitmap> bitmaps = new ArrayList<>();
            //bitmaps.add(getBitmapFromView(mainView));
            height = 0;
            for (int i = 0; i < childcount; i++) {
                View subview = mainView.getChildAt(i);
                if (subview.getId() != findViewById(R.id.empty_view).getId()) {
                    if (subview instanceof SwipeRefreshLayout) {
                        bitmaps.add(getListViewBitmap(listView));
                    } else {
                        bitmaps.add(getBitmapFromView(subview));
                    }
                }
            }
    
            Bitmap bigbitmap = Bitmap.createBitmap(mainView.getMeasuredWidth(), height,
                    Bitmap.Config.ARGB_8888);
            Canvas bigcanvas = new Canvas(bigbitmap);
            bigcanvas.drawColor(Color.WHITE);
            Paint paint = new Paint();
            int iHeight = 0;
            for (int i = 0; i < bitmaps.size(); i++) {
                Bitmap bmp = bitmaps.get(i);
                bigcanvas.drawBitmap(bmp, 0, iHeight, paint);
                iHeight += bmp.getHeight();
                bmp.recycle();
                bmp = null;
            }
            return bigbitmap;
        }
    
        public Bitmap getListViewBitmap(ListView p_ListView) {
            ListView listview = p_ListView;
            ListAdapter adapter = listview.getAdapter();
            int itemscount = adapter.getCount();
            int allitemsheight = 0;
            List<Bitmap> bmps = new ArrayList<Bitmap>();
    
            for (int i = 0; i < itemscount; i++) {
                View childView = adapter.getView(i, null, listview);
                childView.measure(
                        View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());
    
                height = height + childView.getMeasuredHeight();
                childView.setDrawingCacheEnabled(true);
                childView.buildDrawingCache();
                bmps.add(childView.getDrawingCache());
                allitemsheight += childView.getMeasuredHeight();
            }
            Bitmap bigbitmap = Bitmap.createBitmap(listview.getMeasuredWidth(), allitemsheight,
                    Bitmap.Config.ARGB_8888);
            Canvas bigcanvas = new Canvas(bigbitmap);
            bigcanvas.drawColor(Color.WHITE);
            Paint paint = new Paint();
            int iHeight = 0;
            for (int i = 0; i < bmps.size(); i++) {
                Bitmap bmp = bmps.get(i);
                bigcanvas.drawBitmap(bmp, 0, iHeight, paint);
                iHeight += bmp.getHeight();
                bmp.recycle();
                bmp = null;
            }
            return bigbitmap;
        }
    
    
        public Bitmap getBitmapFromView(View view) {
            Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
            height = height + view.getHeight();
            Canvas canvas = new Canvas(returnedBitmap);
            Drawable bgDrawable = view.getBackground();
            if (bgDrawable != null) bgDrawable.draw(canvas);
            else canvas.drawColor(Color.WHITE);
            view.draw(canvas);
            return returnedBitmap;
        }
    

    如果位图是否正在合并,请查看此代码。在我的情况下,它肯定会起作用。