0

1000 行の文字列の部分文字列にスクロールしようとしています。スクロールと UI スレッドにラグがあることに気付きました。だから私は AsyncTask を使用することを考えましたが、その実行時にテキストを取得しますが、スクロールしません。これが私のコードです

 private class LongOperation extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            SharedPreferences score = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
            int chapter_number_bookmark = score.getInt("chapter_number", 89);
            int verse_number_bookmark = score.getInt("verse_number", 1);
            GoToFunction(chapter_number_bookmark,verse_number_bookmark);
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {
            Toast.makeText(getApplicationContext(), "Executed", Toast.LENGTH_SHORT).show();
        }

        @Override
        protected void onPreExecute() {

        }

        @Override
        protected void onProgressUpdate(Void... values) {}
    }

GoTo関数

public void GoToFunction(int chapter, int verse)
    {
        int scroll_amt;
        final TextView shw = (TextView) findViewById(R.id.textViewTab);
        SharedPreferences score = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        int chapter_number = chapter;
        int verse_number = verse;
        String verse_number_str = Integer.toString(verse_number);
        SQLiteDatabase as = openOrCreateDatabase("/"+Environment.getExternalStorageDirectory().getPath()+"/tamil/verse", MODE_PRIVATE, null);
        Cursor a = as.rawQuery("select * from verse"+chapter_number, null);
        a.moveToFirst();
        strTitle = a.getString(a.getColumnIndex("title"));
        final String strContent_book = a.getString(a.getColumnIndex("content"));
        int number = a.getInt(a.getColumnIndex("dialogues"));
        tab.setText("\n\n "+strAthi+strTitle+"\n\n "+strVasa+number+"\n\n "+strContent_book);
        final int offset_dot = strContent_book.indexOf(verse_number_str_dot);
        final int offset_comma = strContent_book.indexOf(verse_number_str_comma);
        a.close();
        as.close();
        if(offset_comma!=-1||offset_dot!=-1)
        {
            if(offset_comma==-1||(offset_dot<offset_comma))
            {
            try
            {
            Toast.makeText(getApplicationContext(), "Athiyayam : "+ chapter_number +" Verse : "+ verse_number, Toast.LENGTH_LONG).show();
            **scroll(offset_dot); //Scroll function**
            }
            catch(Exception e)
            {
                Log.e("Scroll_comma", "Exception", e);
            }
            }
            else
            {
                try
                {
                Toast.makeText(getApplicationContext(), "Athiyayam : "+ chapter_number +" Verse :"+ verse_number, Toast.LENGTH_LONG).show();
                scroll(offset_comma);
                }
                catch(Exception e)
                {
                    Log.e("Scroll", "Exception", e);
                }
            }
        }
        else
        {
            Toast.makeText(getApplicationContext(), "Not found", Toast.LENGTH_LONG).show();
        }
    }

スクロール機能

public void scroll(final int a)
    {
        final TextView shw = (TextView) findViewById(R.id.textViewTab);
        try
        {
        mScroll.post(new Runnable() {
            @Override
            public void run() {
                int y = shw.getLayout().getLineForOffset(a); // e.g. I want to scroll to line 40
                int n = shw.getLayout().getLineTop(y);
                mScroll.scrollTo(0, n);
            }
        });
        }
        catch(Exception e)
        {
        Log.e("scroll", "error", e);
        }   
    }

ここでテキストを取得します。ただし、スクロール機能は実行されません。また、ブックマークアクティビティの開始時にスピナーアクティビティを実行し、PreExecute および PostExecute で実行できる終了時に終了したいと考えています。

4

3 に答える 3

0

この場合、スクロールに asynctask を使用する必要はありません。メインスレッドでコードを実行するだけです。それはうまくいきます。
ユーザーが非同期タスクでスクロール中にスクロールビューをクリックした場合。予期しない動作が発生します。 また、スクロールビューのアクティビティ マニフェストで 1.
も指定します 。
android:hardwareAccelerated="true"
scrollView.setLayerType(View.LAYER_TYPE_HARDWARE, null);

于 2013-10-20T08:01:22.567 に答える
0

あなたのコードから、からメインスレッドを更新しようとしますdoInBackground

       @Override
        protected String doInBackground(String... params) {
               ....
            GoToFunction(chapter_number_bookmark,verse_number_bookmark);
            .....
        }

そんなことはできません。logcatで例外が発生すると確信しています。とにかく更新したい場合は、ハンドラーを介してそれを行います

私たちが持っているとしましょう

private TextView m_txtLog;    
private ScrollView m_sv;

したがって、最後の行までスクロールするには、次のようにする必要があります。

m_sv.post(new Runnable() { 
  public void run() { 
     m_sv.scrollTo(0, m_txtLog.getHeight());                
     } 
  }); 

から実行するServiceか、次のようにAsyncTask使用するHandler場合:

static final int LOG_MSG = 1;

private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String txt;
            switch (msg.what) {
            case LOG_MSG:
                txt = msg.obj.toString();
                m_txtLog.append(txt);

                m_sv.post(new Runnable() { 
                    public void run() { 
                        m_sv.scrollTo(0, m_txtLog.getHeight());                 
                    } 
                });     
                break;
            default:
                super.handleMessage(msg);
            }
        }
    };

そして今、私たちはから書くことができますAsyncTask:

mHandler.sendMessage(mHandler.obtainMessage(LOG_MSG, "Agent started" + "\n\n")); 

ご覧のとおりscrollTo、ハンドラによってラップされています。このように動作します。

(テスト済み)

于 2013-10-20T07:16:12.800 に答える