Я делаю детское приложение, в котором ребенок может рисовать пальцами на развороте книги, как показано ниже.
Основное представление - это не ImageView. Скорее, это настраиваемый вид, расширяющий GLSurfaceView, чтобы разрешить анимацию поворота страницы при перелистывании страниц. Чтобы создать холст, при щелчке по карандашу мой код запускает фрагмент с прозрачным макетом, чтобы можно было рисовать поверх настраиваемого представления.
Работает для каждого цвета в отдельности. Но когда нажимается новый цвет, старые линии удаляются (потому что запускается новый фрагмент), и я могу снова рисовать, используя новый цвет.
Однако в идеале старый рисунок сохраняется (с использованием предыдущего цвета), и пользователь должен иметь возможность продолжать рисовать с новым цветом без повторного запуска фрагмента.
В качестве теста я пока использовал только первые 3 цвета.
В DrawingFragment я действительно смог программно изменить цвет фрагмента (на CYAN), вызвав метод changeColor. Однако мне все еще нужно получить событие щелчка из Activity, которое соответствует каждому цвету.
Основные проблемы:
У меня смутное представление о том, что, возможно, мне следует использовать интерфейс, но я еще не полностью понял, что он делает. Я новичок в kotlin и android, и я буду очень благодарен за любую помощь или предложение.
Основная деятельность
class ReadBooksActivity : Activity() {
var mCurlView: CurlView? = null
var reading_toolbar : View? = null
var isUp = false
var drawColor : Int? = null
var isDrawing = false
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.readbooks_layout)
// Start Page Curl for each page
mCurlView = findViewById(R.id.curl)
mCurlView!!.setSizeChangedObserver(SizeChangedObserver())
mCurlView!!.setCurrentIndex(index)
var bookId = intent.getIntExtra("ID", 0)
Thread(Runnable {
fetchbookpages()
mCurlView!!.setBitmapProvider(BitmapProvider(mBitmaps))
}).start()
mCurlView!!.setEnableTouchPressure(true)
mCurlView!!.set2PagesLandscape(true)
mCurlView!!.setAllowLastPageCurl(true)
// Toggle Reading Toolbar
reading_toolbar = findViewById(R.id.readingtoolbar) as View
// Enable drawing on View
tabtools.setOnClickListener(View.OnClickListener {
showToolbar()
})
tabexit2.setOnClickListener(View.OnClickListener {
hideToolbar()
})
tabexit.setOnClickListener(View.OnClickListener {
onSlideViewButtonClick(reading_toolbar!!)
})
}
fun buttonClicked(view: View) {
//if (!isDrawing) {
if (view.id == R.id.crayon_black) {
drawColor = Color.BLACK
} else if (view.id == R.id.crayon_blue) {
drawColor = Color.BLUE
} else if (view.id == R.id.crayon_green) {
drawColor = Color.GREEN
}
callDrawFragment(drawColor!!)
// }
// isDrawing = true
}
fun callDrawFragment(drawColor : Int) {
val mFragment = DrawingFragment.newInstance(drawColor)
fragmentManager!!
.beginTransaction()
.replace(R.id.mainreadinglayout, mFragment)
.addToBackStack(null)
.commit()
}
}
DrawingFragment
class DrawingFragment: Fragment() {
var drawColor : Int? = null
var drawingView : DrawingView? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.drawing_layout, container, false)
val relativeLayout = view.findViewById(R.id.draw_layout) as RelativeLayout
drawColor = arguments.getInt("color")
var drawingView = DrawingView(activity, drawColor!!)
relativeLayout.addView(drawingView)
changeColor(drawingView)
return view
}
fun changeColor(view: DrawingView) {
var currentPaint = Paint()
currentPaint.setColor(Color.CYAN)
currentPaint.isAntiAlias = true
currentPaint.isDither = true
currentPaint.style = Paint.Style.STROKE
currentPaint.strokeJoin = Paint.Join.ROUND
currentPaint.strokeCap = Paint.Cap.ROUND
currentPaint.strokeWidth = 10f
view.setPaint(currentPaint)
}
companion object {
fun newInstance(color: Int): DrawingFragment {
val args = Bundle()
args.putInt("color", color)
val fragment = DrawingFragment()
fragment.arguments = args
return fragment
}
}
}
DrawingView
class DrawingView(context: Context, color : Int) : View(context) {
var mPaint: Paint? = null
val mPath: Path
init {
mPaint = Paint()
mPaint!!.isAntiAlias = true
mPaint!!.isDither = true
mPaint!!.color = color
mPaint!!.style = Paint.Style.STROKE
mPaint!!.strokeJoin = Paint.Join.ROUND
mPaint!!.strokeCap = Paint.Cap.ROUND
mPaint!!.strokeWidth = 10f
mPath = Path()
}
override fun onDraw(canvas: Canvas) {
canvas.drawPath(mPath, mPaint)
super.onDraw(canvas)
canvas.drawColor(Color.TRANSPARENT)
}
fun setPaint(mPaint: Paint) {
this.mPaint = mPaint
return
}
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> mPath.moveTo(event.x, event.y)
MotionEvent.ACTION_MOVE -> {
mPath.lineTo(event.x, event.y)
invalidate()
}
MotionEvent.ACTION_UP -> {
}
}
return true
}
}





Я понял это, сославшись на кнопки активности во фрагменте.
var btn_black = (getActivity()).findViewById(R.id.crayon_black) as ImageView
var btn_blue = (getActivity()).findViewById(R.id.crayon_blue) as ImageView
var btn_green = (getActivity()).findViewById(R.id.crayon_green) as ImageView
А затем установка слушателей onclick во фрагменте
btn_black.setOnClickListener(View.OnClickListener {
changeColor(drawingView, Color.BLACK)
})
btn_blue.setOnClickListener(View.OnClickListener {
changeColor(drawingView, Color.BLUE)
})
btn_green.setOnClickListener(View.OnClickListener {
changeColor(drawingView, Color.GREEN)
})
А затем переустановите onclicklisteners для активности на backpressed. У меня также был booleanTag, чтобы указать, работает ли фрагмент или нет.
override fun onBackPressed() {
setColorOnClickListeners()
booleanTag = "false"
crayon_black.setTag(booleanTag)
if (mCurlView!!.getIsUp()) {
slideDown(reading_toolbar!!)
mCurlView!!.setIsUp(!isUp)
}
super.onBackPressed()
}
SetcolorOnClicklistener () выглядит следующим образом:
fun setColorOnClickListeners() {
crayon_black.setOnClickListener(View.OnClickListener {
buttonClicked(crayon_black)
})
crayon_blue.setOnClickListener(View.OnClickListener {
buttonClicked(crayon_blue)
})
// etc...
}
buttonClicked:
fun buttonClicked(view: View) {
booleanTag = crayon_black.tag as String
if (booleanTag == "false") {
if (view.id == R.id.crayon_black) {
drawColor = Color.BLACK
} else if (view.id == R.id.crayon_blue) {
drawColor = Color.BLUE
} else if (view.id == R.id.crayon_green) {
drawColor = Color.GREEN
} else if (view.id == R.id.crayon_orange) {
drawColor = Color.parseColor("#FFA500")
} else if (view.id == R.id.crayon_pink) {
drawColor = Color.parseColor("#ec5db8")
} else if (view.id == R.id.crayon_red) {
drawColor = Color.RED
} else if (view.id == R.id.crayon_violet) {
drawColor = Color.parseColor("#8862ba")
} else if (view.id == R.id.crayon_white) {
drawColor = Color.WHITE
} else if (view.id == R.id.crayon_yellow) {
drawColor = Color.YELLOW
}
callDrawFragment(drawColor!!)
booleanTag = "true"
crayon_black.setTag(booleanTag)
}
}
Все еще нужно обработать некоторые вещи в DrawingView для изменения цвета, но это решило большинство моих проблем.