鍍金池/ 問答/Android/ 自定義控件的效果需要根據(jù)網(wǎng)絡(luò)數(shù)據(jù)動態(tài)調(diào)整,如何準確的處理

自定義控件的效果需要根據(jù)網(wǎng)絡(luò)數(shù)據(jù)動態(tài)調(diào)整,如何準確的處理

例如 我的自定義控件是一個TextView,我現(xiàn)在需要訪問網(wǎng)絡(luò)獲取一個數(shù)字,將數(shù)字進行一定處理顯示出來,

例如請求返回100,然后將這個數(shù)字乘以TextView的寬,顯示在TextView上。

存在的問題 ,

  1. 因為適配原因,TextView的寬度不是固定的
  2. 我在Activity#onCreate()中訪問網(wǎng)絡(luò),是不能確保請求成功發(fā)生在TextView#getHeight不等于0的。
  3. 訪問網(wǎng)絡(luò)時機不想改變

我現(xiàn)在可以這樣處理:

  1. 為控件注冊一個在寬高可以獲取時觸發(fā)的監(jiān)聽器
  2. 請求網(wǎng)絡(luò)
  3. 請求網(wǎng)絡(luò)成功,
  4. 判斷控件的監(jiān)聽是否被觸發(fā),
    4.1 如果監(jiān)聽被觸發(fā)有那么直接處理數(shù)據(jù)
    4.2 如果監(jiān)聽未觸發(fā),那么繼續(xù)等待監(jiān)聽被觸發(fā),監(jiān)聽觸發(fā)時處理數(shù)據(jù)

這種解決方法,各種監(jiān)聽和判斷,而且因為監(jiān)聽是在主線程被觸發(fā),而我的網(wǎng)絡(luò)請求和數(shù)據(jù)處理都在不同的線程,數(shù)據(jù)處理完畢又要回到主線程,這代碼寫起來簡直酸爽。

我需要兩個數(shù)據(jù)

  • 請求網(wǎng)絡(luò)返回的數(shù)據(jù)
  • 控件的大小

由于網(wǎng)絡(luò)原因,我不能確保他們的先后順序,有什么辦法可以

回答
編輯回答
拽很帥

大概明白了。。是一個線程協(xié)作的問題?

為控件注冊一個在寬高可以獲取時觸發(fā)的監(jiān)聽器

這個相當容易。。。不說話,看碼:

v.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {
                            v.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                            int height=v.getHeight();
                        }
                    });

網(wǎng)絡(luò)請求線程

就提供一個思路,用ReentrantLock,在Activity#onCreate()lock.lock(),在OnGlobalLayoutListenerlock.unlock(),在線程中這么寫:

new Thread(new Runnable() {
                        @Override
                        public void run() {
                            //你的網(wǎng)絡(luò)請求處理。。。。
                            try {
                                lock.lock();
                                view.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        LayoutParams lp=v.getLayoutParams().height=123;
                                        view.setLayoutParams(lp);
                                    }
                                });
                            }
                            finally {
                                lock.unlock();
                            }
                        }
                    }).start();

當然這不是最佳方案。。。如果lock時機不對可能會導致鎖死。
如果你沒有更好的方案,用這個也未嘗不可。

如果還有問題歡迎追問

2018年3月17日 00:07