SeekBar listenner завершает работу приложения при нахождении во фрагменте

#java #android #android-studio

#java #Android #android-studio

Вопрос:

У меня есть панель поиска внутри фрагмента, и когда я запускаю приложение, оно выходит из строя. Фрагмент является частью основного действия. Вот код:

 public class PalleteFragment extends Fragment {

  public TextView textView;
  private CanvasView canvas;

  public PalleteFragment() {
    // Required empty public constructor
  }


  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_pallete, container, false);
  }

  @Override
  public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekBar);
    textView = (TextView) view.findViewById(R.id.textView);
    textView.setText("Pen size: "   seekBar.getProgress());

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            canvas.setStrokeWidth(seekBar.getProgress());
            textView.setText("Pen size: "   seekBar.getProgress());
        }

        ...
    });
  }
}
  

Чего-то не хватает, что мне нужно написать?

Вот ошибка, возникающая при сбое приложения: введите описание изображения здесь

Короче говоря, это класс CanvasView:

 public class CanvasView extends View implements View.OnTouchListener {


private Paint mPaint;
private Path mPath;
private int mDrawColor;
private int mBackgroundColor;
private Canvas mExtraCanvas;
private Bitmap mExtraBitmap;
private int strokeWidth;

private GestureDetector mGestureDetector;

private static final float TOUCH_TOLERANCE = 4;
private float mX, mY;

CanvasView(Context context) {

    super(context);
    setOnTouchListener(this);
    strokeWidth = 10;

    mBackgroundColor = ResourcesCompat.getColor(getResources(),
            R.color.simpleWhite, null);
    mDrawColor = ResourcesCompat.getColor(getResources(),
            R.color.simpleBlack, null);

    mPath = new Path();

    mPaint = new Paint();
    mPaint.setColor(mDrawColor);

    mPaint.setAntiAlias(true);

    mPaint.setDither(true);

    mPaint.setStyle(Paint.Style.STROKE); // default: FILL
    mPaint.setStrokeJoin(Paint.Join.ROUND); // default: MITER
    mPaint.setStrokeCap(Paint.Cap.ROUND); // default: BUTT
    mPaint.setStrokeWidth(strokeWidth);
}


public CanvasView(Context context, AttributeSet attributeSet,GestureDetector mGestureDetector) {
    super(context);

    this.mGestureDetector = mGestureDetector;
    strokeWidth = 10;

    setOnTouchListener(this);
    mBackgroundColor = ResourcesCompat.getColor(getResources(),
            R.color.simpleWhite, null);
    mDrawColor = ResourcesCompat.getColor(getResources(),
            R.color.simpleBlack, null);

    mPath = new Path();

    mPaint = new Paint();
    mPaint.setColor(mDrawColor);

    mPaint.setAntiAlias(true);
    mPaint.setDither(true);

    mPaint.setStyle(Paint.Style.STROKE); // default: FILL
    mPaint.setStrokeJoin(Paint.Join.ROUND); // default: MITER
    mPaint.setStrokeCap(Paint.Cap.ROUND); // default: BUTT
    mPaint.setStrokeWidth(strokeWidth);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.drawBitmap(mExtraBitmap, 0, 0, null);
    mPaint.setStrokeWidth(strokeWidth);

}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touchStart(x, y);
            updateColor(PreferenceManager.getDefaultSharedPreferences(getContext()).getInt("color",getResources().getColor(R.color.simpleBlack)));
            setStrokeWidth(PreferenceManager.getDefaultSharedPreferences(getContext()).getInt("stroke", 0));
            break;
        case MotionEvent.ACTION_MOVE:
            touchMove(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touchUp();
            break;
        default:
            // Do nothing.
    }
    return true;
}

private void touchStart(float x, float y) {
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
}

private void touchMove(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x   mX)/2, (y   mY)/2);
        mX = x;
        mY = y;
        mExtraCanvas.drawPath(mPath, mPaint);
    }
}

private void touchUp() {
    mPath.reset();
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    mGestureDetector.onTouchEvent(event);
    return false;
}

public void erase(){
    mExtraCanvas.drawColor(ResourcesCompat.getColor(getResources(),
            R.color.simpleWhite, null));
}

public void setStrokeWidth(int width) {
    mPaint.setStrokeWidth(width);
}
  

}

Класс очень длинный, поэтому я пропустил другие методы, которые не были необходимы для этого вопроса.

Вот XML-файл из фрагмента:

 <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   xmlns:tools="http://schemas.android.com/tools"
   android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <SeekBar
            android:id="@ id/seekBar"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <TextView
            android:id="@ id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Pen Size: " />
    </LinearLayout>
  

Вот каталоги приложения:

введите описание изображения здесь

Комментарии:

1. Пожалуйста, добавьте журнал сбоев, в котором возникает исключение.

2. canvas.setStrokeWidth(SeekBar.getProgress()); Я не вижу, чтобы вы инициализировали холст во фрагменте.

3. @AliEid холст уже инициализирован в другом классе, я думаю

4. Что это за холст в любом случае? Даже если вы выполнили инициализацию в другом классе, текущий фрагмент этого не знает. Если этот вид холста отсутствует в макете fragment_pallete, он выдаст NPE. Можете ли вы добавить это к вопросу?

5. Можете ли вы попробовать удалить canvas.setStrokeWidth(SeekBar.getProgress()); и создать приложение и запустить его, прежде чем продолжить?

Ответ №1:

Используйте свой CanvasView внутри XML-файла вашего фрагмента:

    <com.lionsilva.newpaint.customviews.CanvasView
        android:id="@ id/canvas_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
  

Затем инициализируйте его, как любое другое представление:

   private CanvasView canvas;
  canvas = view.findViewById(R.id.canvas_view);
  canvas.setStrokeWidth( seekBar.getProgress() );
  

Комментарии:

1. CanvasView уже открыт в xml основного действия. Если я открою его внутри фрагмента, он создаст представление, которое мне не нужно

2. Итак, вы передаете данные из этого фрагмента в класс mainactivity?

3. В ваших кодах у вас было исключение NullPointerException, потому что вы использовали представление, которого нет в вашем фрагменте. Я не уверен, что вы пытаетесь сделать. Пожалуйста, уточните подробнее в вопросе, иначе я больше не могу помочь! Спасибо!

4. нет. основное действие состоит из двух фрагментов. один фрагмент содержит панель поиска, другой — холст. существует класс с именем CanvasView, который рисует на холсте. Мне нужно передать значение этому классу

5. Вы должны были уже упомянуть об этом. Вам нужно сделать CanvasView общедоступным внутри вашего CanvasFragment. Затем попробуйте в вашем PalleteFragment onViewCreated CanvasFragment cFragment = new CanvasFragment(); cFragment.canvas.setStrokeWidth …