【问题标题】:Limit multiple seekbars to a maximum of 100% overall将多个搜索栏限制为最大 100%
【发布时间】:2013-08-15 13:14:35
【问题描述】:

我有 5 个搜索栏,我希望用户能够操作它们。搜索栏相互依赖,因此如果一个设置为 100%,所有其他搜索栏都必须为 0%。我已经能够使用this post 中的代码来实现这一点,但是在操作搜索栏时它会出现故障并且搜索栏会四处跳动。例如,默认情况下,我将所有搜索栏设置为 20%。为了将 seekbar_1 提高 20%,您需要降低另一个 seekbar 的值(比如 seekbar_2 降低 20%)。这释放了 seekbar_1 可以使用的 20%。我的问题是搜索栏的实际触摸和移动,我认为它会跳来跳去,因为我在 onProgressChanged 方法中进行了各种计算。我在下面附上了我的代码。有没有更简单的方法来实现这一点?任何帮助将不胜感激。

public class MainActivity extends Activity implements OnSeekBarChangeListener{
public SeekBar sb1,sb2,sb3,sb4,sb5;
public TextView tv1,tv2,tv3,tv4,tv5;
public int mPercentRemaining, mPercentTotal, mPercentUsed;
public int mCurrentPercent;

@Override
public void onCreate(Bundle savedInstanceState) 
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

sb1=(SeekBar) findViewById(R.id.seekBar1);
sb2=(SeekBar) findViewById(R.id.seekBar2);
sb3=(SeekBar) findViewById(R.id.seekBar3);
sb4=(SeekBar) findViewById(R.id.seekBar4);
sb5=(SeekBar) findViewById(R.id.seekBar5);

tv1=(TextView) findViewById(R.id.textView1);
tv2=(TextView) findViewById(R.id.textView2);
tv3=(TextView) findViewById(R.id.textView3);
tv4=(TextView) findViewById(R.id.textView4);
tv5=(TextView) findViewById(R.id.textView5);

sb1.setOnSeekBarChangeListener(this);
sb2.setOnSeekBarChangeListener(this);
sb3.setOnSeekBarChangeListener(this);
sb4.setOnSeekBarChangeListener(this);
sb5.setOnSeekBarChangeListener(this);

mPercentTotal = 100;
mPercentUsed = 100; //Seekbars are all set to 20% by default
mPercentRemaining = mPercentTotal - mPercentUsed;

}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) 
{
switch (seekBar.getId()) 
{
case R.id.seekBar1:
    if((progress - mCurrentPercent) <= mPercentRemaining || mCurrentPercent >= progress)
        tv1.setText(progress);
    else
    {
        seekBar.setProgress(mCurrentPercent);
        tv1.setText(mCurrentPercent);
    }
    break;
case R.id.seekBar2:
    if((progress - mCurrentPercent) <= mPercentRemaining || mCurrentPercent >= progress)
        tv2.setText(progress);
    else
    {
        seekBar.setProgress(mCurrentPercent);
        tv2.setText(mCurrentPercent);
    }
    break;
case R.id.seekBar3:
    if((progress - mCurrentPercent) <= mPercentRemaining || mCurrentPercent >= progress)
        tv3.setText(progress);
    else
    {
        seekBar.setProgress(mCurrentPercent);
        tv3.setText(mCurrentPercent);
    }
    break;
case R.id.seekBar4:
    if((progress - mCurrentPercent) <= mPercentRemaining || mCurrentPercent >= progress)
        tv4.setText(progress);
    else
    {
        seekBar.setProgress(mCurrentPercent);
        tv4.setText(mCurrentPercent);
    }
    break;
case R.id.seekBar5:
    if((progress - mCurrentPercent) <= mPercentRemaining || mCurrentPercent >= progress)
        tv5.setText(progress);
    else
    {
        seekBar.setProgress(mCurrentPercent);
        tv5.setText(mCurrentPercent);
    }
    break;

}

mPercentUsed = sb1.getProgress() + sb2.getProgress() + sb3.getProgress() + sb4.getProgress() + sb5.getProgress();
mPercentRemaining = mPercentTotal - mPercentUsed;

}

@Override
public void onStartTrackingTouch(SeekBar arg0) 
{
mCurrentProgress = seekBar.getProgress();
}

@Override
public void onStopTrackingTouch(SeekBar arg0) 
{

// TODO Auto-generated method stub
}}

【问题讨论】:

    标签: android progress-bar seekbar android-progressbar


    【解决方案1】:

    例如,默认情况下,我将所有搜索栏设置为 20%。为了 将 seekbar_1 上移 20%,你会降低另一个 seekbar 的值(比如 seekbar_2 20%)。这释放了 seekbar_1 可以使用的 20%。 我的问题是搜索栏的实际触摸和移动,它跳跃 我认为是因为我在 onProgressChanged 方法。我在下面附上了我的代码。有没有 更简单的实现方式?

    查看下面的代码,了解如何做你想做的事。有大量文档,因此理解它应该没有问题:

    private static final int TOTAL_AMOUNT = 100; // the maximum amount for all SeekBars
    // stores the current progress for the SeekBars(initially each SeekBar has a
    // progress of 20)
    private int[] mAllProgress = { 20, 20, 20, 20, 20 };
    
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            // find out which SeekBar triggered the event so we can retrieve its saved current
            // progress
            int which = whichIsIt(seekBar.getId());
            // the stored progress for this SeekBar
            int storedProgress = mAllProgress[which];
            // we basically have two cases, the user either goes to the left or to
            // the right with the thumb. If he goes to the right we must check to
            // see how much he's allowed to go in that direction(based on the other
            // SeekBar values) and stop him if he the available progress was used. If
            // he goes to the left use that progress as going back
            // and freeing the track isn't a problem.
            if (progress > storedProgress) {
                // how much is currently available based on all SeekBar progress
                int remaining = remaining();
                // if there's no progress remaining then simply set the progress at
                // the stored progress(so the user can't move the thumb further)
                if (remaining == 0) {
                    seekBar.setProgress(storedProgress);
                    return;
                } else {
                    // we still have some progress available so check that available
                    // progress and let the user move the thumb as long as the
                    // progress is at most as the sum between the stored progress
                    // and the maximum still available progress
                    if (storedProgress + remaining >= progress) {
                        mAllProgress[which] = progress;
                    } else {
                        // the current progress is bigger then the available
                        // progress so restrict the value
                        mAllProgress[which] = storedProgress + remaining;
                    }
                }
            } else if (progress <= storedProgress) {
                // the user goes left so simply save the new progress(space will be
                // available to other SeekBars)
                mAllProgress[which] = progress;
            }
        }
    
        /**
         * Returns the still available progress after the difference between the
         * maximum value(TOTAL_AMOUNT = 100) and the sum of the store progresses of
         * all SeekBars.
         * 
         * @return the available progress.
         */
        private final int remaining() {
            int remaining = TOTAL_AMOUNT;
            for (int i = 0; i < 5; i++) {
                remaining -= mAllProgress[i];
            }
            if (remaining >= 100) {
                remaining = 100;
            } else if (remaining <= 0) {
                remaining = 0;
            }
            return remaining;
        }
    
        private int whichIsIt(int id) {
            switch (id) {
            case R.id.seekBar1:
                return 0; // first position in mAllProgress
            case R.id.seekBar2:
                return 1;
            case R.id.seekBar3:
                return 2;
            case R.id.seekBar4:
                return 3;
            case R.id.seekBar5:
                return 4;
            default:
                throw new IllegalStateException(
                        "There should be a Seekbar with this id(" + id + ")!");
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      相关资源
      最近更新 更多