【问题标题】:Progress Bar findviewbyid returns null进度条 findviewbyid 返回 null
【发布时间】:2017-04-01 18:13:06
【问题描述】:

帮帮我吧,这越来越令人沮丧了!

我正在做一个聊天应用程序,每次用户按下发送按钮时,我都会以编程方式将视图添加到线性布局,代码如下:

public  void appendToMessageHistory(String id,String uname, String messa,String messageType, final String filepath, String DownloadStatus,boolean internet,int type) {


    //TextView tv=new TextView(Messaging.this);
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(Width, LinearLayout.LayoutParams.WRAP_CONTENT);
    lp.setMargins(0, 10, 0, 0);

    View v = getLayoutInflater().inflate(R.layout.message_entity, null);


    TextView mess;
    TextView time;
    final ImageView iv;
    final ProgressBar progressBar;
    ImageView statusiv;
    if (friend.userName.equals(uname)) {
        v = getLayoutInflater().inflate(R.layout.message_entity, null);
        v.setId(Integer.parseInt(id));
        mess = (TextView) v.findViewById(R.id.message_entity_message);
        time = (TextView) v.findViewById(R.id.message_entity_time);
        iv = (ImageView) v.findViewById(R.id.message_entity_imageview);
        statusiv = (ImageView) v.findViewById(R.id.imageView);
        progressBar = (ProgressBar) v.findViewById(R.id.message_entity_progressbar);
    } else {
        v = getLayoutInflater().inflate(R.layout.message_entity_right, null);
        lp.gravity = Gravity.RIGHT;
        v.setId(Integer.parseInt(id));
        mess = (TextView) v.findViewById(R.id.message_entity_right_message);
        time = (TextView) v.findViewById(R.id.message_entity_right_time);
        iv = (ImageView) v.findViewById(R.id.message_entity_right_imageview);
        statusiv = (ImageView)v.findViewById(R.id.imageViewleft);
        progressBar = (ProgressBar) v.findViewById(R.id.message_entity_Right_progressbar);
    }

    try {
        progressBar.setId(Integer.parseInt(id));

    } catch (Exception e) {
        e.printStackTrace();
    }

    if (messageType != null) {
        if (messageType.equals(MessageInfo.MESSAGE_TYPE_PIC)) {
            iv.setImageBitmap(ImageHandlet.GetBitmapFromPath(filepath));
            progressBar.setVisibility(View.GONE);
            iv.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setDataAndType(Uri.parse("file://" + filepath), "image/png");
                    startActivity(intent);
                    Log.d("FIlePAth", filepath);
                }
            });

        } else if (messageType.equals(MessageInfo.MESSAGE_TYPE_VIDEO)) {
            if (DownloadStatus.equals(LocalStorageHandler.DOWNLOADED)) {
                if(!(friend.userName.equals(uname))) {
                    if (type != 3) {
                        Bitmap bitTh = ThumbnailUtils.createVideoThumbnail(filepath, MediaStore.Images.Thumbnails.MINI_KIND);
                        iv.setImageBitmap(bitTh);
                        progressBar.setVisibility(View.GONE);
                        iv.setOnClickListener(new OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(filepath));
                                intent.setDataAndType(Uri.parse(filepath), "video/mp4");
                                startActivity(intent);

                            }
                        });
                    } else {
                        Log.w("Zipping","Progress Bar");
                        progressBar.setVisibility(View.VISIBLE);
                    }
                } else {
                    Bitmap bitTh = ThumbnailUtils.createVideoThumbnail(filepath, MediaStore.Images.Thumbnails.MINI_KIND);
                    iv.setImageBitmap(bitTh);
                    progressBar.setVisibility(View.GONE);
                    iv.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(filepath));
                            intent.setDataAndType(Uri.parse(filepath), "video/mp4");
                            startActivity(intent);

                        }
                    });
                }
            } else if (DownloadStatus.equals(LocalStorageHandler.NotDOWNLOADED)) {
                iv.setTag(id);
                iv.setImageResource(R.drawable.download);
                iv.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        progressBar.setVisibility(View.VISIBLE);
                        Cursor c = localstoragehandler.getIDnfo(iv.getTag().toString());
                        String filepath = "";
                        //Toast.makeText(getApplication(),iv.getTag().toString()+" iD " +iv.getId(),Toast.LENGTH_SHORT).show();

                        while (c.moveToNext()) {
                            String msg0 = c.getString(0);
                            String msg2 = c.getString(2);
                            String msg3 = c.getString(3);
                            String msg4 = c.getString(4);
                            String msg5 = c.getString(5);
                            String msg6 = c.getString(6);

                            filepath = msg5;

                            Log.d("-----------Vedio-----", "------------------");
                            Log.d("DATABASE---------", msg0);
                            Log.d("DATABASE-------", msg2);
                            Log.d("DATABASE---------", msg3);
                            Log.d("DATABASE-----", msg4 + "");
                            Log.d("DATABASE-------", msg5 + "");
                            Log.d("DATABASE----------", msg6 + "");
                            Log.d("--------END-------", "-------END-----------");


                        }

                        Toast.makeText(getApplicationContext(), filepath.toString() + iv.getTag().toString(), Toast.LENGTH_SHORT).show();

                        DownloadFileFromURL downloadFileFromURL = new DownloadFileFromURL(filepath, iv.getTag().toString());
                        downloadFileFromURL.execute("");
                    }
                });
            }
        } else {
            iv.setVisibility(View.GONE);
            progressBar.setVisibility(View.GONE);
        }
    }
    if(!(messageType.equals(MessageInfo.MESSAGE_TYPE_VIDEO))) {
        if (!internet) {
            statusiv.setImageResource(R.drawable.noconnectionl);
        }
    }
    mess.setText(messa);
    //time.setText(sendt);
    v.setLayoutParams(lp);
    final View lastview = v;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mEssageBox.addView(lastview);

        }
    });
    scrollView.post(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(View.FOCUS_DOWN);
            messageText.requestFocus();
        }
    });
}

这里是对话框的 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layoutDirection="ltr">

<ImageView
    android:id="@+id/imageViewleft"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:src="@drawable/chaticion" />

<RelativeLayout
    android:id="@+id/tests"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#83e3ed"
    android:layoutDirection="rtl"
    android:padding="5dp"
    android:layout_alignParentTop="true"
    android:layout_toLeftOf="@+id/imageViewleft"
    android:layout_toStartOf="@+id/imageViewleft">


    <TextView
        android:id="@+id/message_entity_right_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginEnd="19dp"
        android:layout_marginRight="19dp"
        android:text="Large ffText"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textIsSelectable="true" />

    <TextView
        android:id="@+id/message_entity_right_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/message_entity_right_message"
        android:paddingRight="10dp"
        android:text="Small Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />


    <ImageView
        android:id="@+id/message_entity_right_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="false"
        android:layout_below="@+id/message_entity_right_time"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"

        android:src="@drawable/ic_launcher" />

    <ProgressBar
        android:id="@+id/message_entity_Right_progressbar"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="false"
        android:layout_below="@+id/message_entity_right_time"


        android:indeterminate="false"
        android:visibility="invisible" />


</RelativeLayout>

这是发送视频消息的代码:

final String message = messageText.getText().toString();
    final Long rowid = localstoragehandler.insert(imService.getUsername(), friend.userName, message, MessageInfo.MESSAGE_TYPE_VIDEO, ZippedVideoPath, LocalStorageHandler.DOWNLOADED); //insert data into db and get to chat_id
    appendToMessageHistory(rowid + "", imService.getUsername(), message, MessageInfo.MESSAGE_TYPE_VIDEO, ZippedVideoPath, LocalStorageHandler.DOWNLOADED, internet,3);// append the video with type 3 to just display the progress 
    messageText.setText("Video");
    String newstr = null;
    // intialize the asynctask to upload the video
    class UploadVideo extends AsyncTask<Void, Void, String> {
        ProgressDialog uploading;
        View V;
        UploadVideo(View v){
            V = v;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //          uploading = ProgressDialog.show(Messaging.this, "Uploading File", "Please wait...", false, false);
        }

        @Override
        protected String doInBackground(Void... params) {
            return imService.sendVideoMessage(imService.getUsername(), friend.userName, message, MessageInfo.MESSAGE_TYPE_VIDEO, "", ZippedVideoPath);
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
         //   RelativeLayout v = (RelativeLayout) V.findViewById(rowid.intValue());
        //    Log.w("Zipping",v.toString());
     //       ProgressBar progressBar1 = (ProgressBar) V.findViewById(R.id.message_entity_Right_progressbar);
      //      Log.w("Zipping",progressBar1.toString());
            //          ImageView iv = (ImageView) v.findViewById(R.id.message_entity_right_imageview);
       //     progressBar1.setVisibility(View.GONE);
        //  Log.d("POST Execute", s + "");

            //textViewResponse.setText(Html.fromHtml("<b>Uploaded at <a href='" + s + "'>" + s + "</a></b>"));
            //textViewResponse.setMovementMethod(LinkMovementMethod.getInstance());
    // here i am preparing the path so when the compress is done to save into.
        }
    }
    if (null != absolute && absolute.length() > 0) {
        int endIndex = absolute.lastIndexOf("/");
        if (endIndex != -1) {
            newstr = absolute.substring(endIndex, absolute.length()); // not forgot to put check if(endIndex != -1)
        }
    }
    Log.w("Zipping", newstr);
    final File videosdir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/videos/");
    if (!videosdir.exists()) {
        videosdir.mkdirs();
    }
    ZippedVideoPath = videosdir.getAbsolutePath() + "/" + newstr;
    Log.w("Zipping", ZippedVideoPath);
    // here i got the ffmpeg library from the net to compress the video and i'm preparing the commands
    String[] complexCommand = {"-y", "-i", absolute, "-strict", "experimental", "-r", "25", "-vcodec", "mpeg4", "-b:a", "150k", "-ab", "48000", "-ac", "2", "-ar", "22050", ZippedVideoPath};
    FFmpeg ffmpeg = FFmpeg.getInstance(getBaseContext());
    try {
        // to execute "ffmpeg -version" command you just need to pass "-version"
        ffmpeg.execute(complexCommand, new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {
                Log.w("Zipping", "started");
            }

            @Override
            public void onProgress(String message) {
            }

            @Override
            public void onFailure(String message) {
                Log.w("Zipping", message);
            }

            @Override
            public void onSuccess(String message1) {
                Log.w("Zipping","Success");
                RelativeLayout v = (RelativeLayout) mEssageBox.findViewById(rowid.intValue());
                Log.w("VideoView",v.toString());
                ProgressBar progressBar = (ProgressBar) v.findViewById(R.id.message_entity_Right_progressbar);
                ImageView iv = (ImageView) v.findViewById(R.id.message_entity_right_imageview);
            //  progressBar.setVisibility(View.GONE);
                Bitmap bitTh = ThumbnailUtils.createVideoThumbnail(ZippedVideoPath, MediaStore.Images.Thumbnails.MINI_KIND);
                iv.setImageBitmap(bitTh);
                progressBar.setVisibility(View.GONE);
                iv.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(ZippedVideoPath));
                        intent.setDataAndType(Uri.parse(ZippedVideoPath), "video/mp4");
                        startActivity(intent);

                    }
                });
                UploadVideo uv = new UploadVideo(v);
                uv.execute();
            }

            @Override
            public void onFinish() {
            }
        });
    } catch (FFmpegCommandAlreadyRunningException e) {
        Log.w("Zipping", e.toString());
    }
}

现在解决问题,当我在 sendvideomessage ffmpeg onsuccess 回调中调用进度条的 findviewbyid 时,它返回 null,即使位于相同布局中的 imageview 的 findviewbyid 返回视图!所以请告诉我是什么问题

public void onSuccess(String message1) {
                Log.w("Zipping","Success");
                RelativeLayout v = (RelativeLayout) mEssageBox.findViewById(rowid.intValue()); ;
                ProgressBar progressBar = (ProgressBar) v.findViewById(R.id.message_entity_Right_progressbar); // this keeps returning null!
                ImageView iv = (ImageView) v.findViewById(R.id.message_entity_right_imageview); // returns the view
            //  progressBar.setVisibility(View.GONE);
                Bitmap bitTh = ThumbnailUtils.createVideoThumbnail(ZippedVideoPath, MediaStore.Images.Thumbnails.MINI_KIND);
                iv.setImageBitmap(bitTh);
                progressBar.setVisibility(View.GONE);
                iv.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(ZippedVideoPath));
                        intent.setDataAndType(Uri.parse(ZippedVideoPath), "video/mp4");
                        startActivity(intent);

                    }
                });
                UploadVideo uv = new UploadVideo(v);
                uv.execute();
            }

谢谢!

【问题讨论】:

  • 第一次按发送时它总是返回null还是有效?
  • 您的意思是在 appendToMessageHistory 中吗?不,它不返回 null 进度可见性设置为可见,我可以看到它在我面前旋转,但在成功时它总是返回 null

标签: android ffmpeg


【解决方案1】:

您试图将视图作为“v”的子视图,这似乎是进度条的兄弟,而不是父视图。

编辑:但是由于您似乎重用了 rowid 作为视图 id,因此遵循代码有点困难。这甚至是你的意图吗? 以编程方式添加视图时,它们不会获得任何 id,因此您很难找到以 rowid 作为 id 的视图。我想你可以使用标签并遍历视图来找到标签,但这是一个非常低效的解决方案。

(尝试使用视图根来查找视图,或者至少使用您正在寻找的视图的父级来查找视图。 另外,不要多次这样做,将您的视图保存为成员。)

此外,不要在无限增长的线性布局中动态添加视图。你最终会耗尽内存。使用 recyclerview 和 n 适配器在滚动时根据需要创建、重用和销毁视图。

【讨论】:

  • 我听说过内存问题,但我在编码方面走得太远了,现在要更改所有内容,我正在设置视图 row_id,它是数据库中的聊天 ID,以便更容易findviewbyid 所以我不必像你建议的那样遍历所有视图。
  • 嗯,每个程序员都会遇到一个问题,迫使你重新思考和重新设计。重构是我可能在 50% 的时间里改进我的代码的方式。不要仅仅因为你已经花了一些时间就朝着错误的方向继续前进。并且不要尝试使用行 ID 作为视图 ID,因为视图 ​​ID 是您在 xml 中静态分配的视图 ID,其值由 aapt 在构建期间自动生成。
  • 我在某处读到自动生成的视图没有 id...,我知道您必须重构所有内容是什么意思,但我根本没有时间...真的我在工作一个人
  • 那你就有麻烦了..迟早你会后悔没有从一开始就做好事。除非这只是一个学校作业或。一些短暂的。
  • 目前确实是一个临时项目。
【解决方案2】:

您好,根据 JHH 的回答,我尝试了他建议为布局设置标签并从那里调用它的方法,但它不起作用,所以我尝试为进度条设置标签,并为进度条设置 findviewbytag 和有效!奇怪的行为,无论如何感谢您的帮助!

【讨论】:

    【解决方案3】:

    由于您使用的是最终变量:

    final ProgressBar progressBar;
    

    它只会被初始化一次。您不能在同一上下文中为其重新分配新值。

    尝试删除 final 或为两个不同的布局使用单独的 ProgressBar 变量,看看是否有效。

    如果有帮助请告诉我!

    【讨论】:

    • 按照 JHH 的建议,使用 RecyclerView。让事情变得简单高效!
    • 如果这是第二次尝试分配变量时代码无法编译的问题。显然这不是问题。
    • 这正是我的想法,JHH
    猜你喜欢
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    相关资源
    最近更新 更多