Я пытаюсь перехватить каждый виджет вида, который накачивается в моей активности и переопределяет функциональность setText этого представления, если он существует.
Так что если TextView имеет android: text = "bla" в XML-макете, я хочу иметь возможность перехватить это и, возможно, добавить ** в конце всех текстов, заданных из xml.
Один из способов, который, кажется, близок к тому, что мне нужно, – использовать инфразрядник Custom Layout.
LayoutInflaterCompat.setFactory(layoutInflator, InflatorOnSteriods(this))
и в моем InflatorOnSteriods переопределить onCreateView, а затем перехватить все виды там .. этот подход, похоже, не работает вообще. onCreateView никогда не вызывается.
Я также попытался использовать cloneInContext
LayoutInflaterCompat.setFactory(layoutInflater.cloneInContext(this), InflatorOnSteriods(this))
Но не повезло, может быть, мой подход совершенно неверен. Я также открыт для другого способа, когда я могу перехватить все представленные представления и конкретный набор определенного атрибута для этого представления. Очень важно убедиться, что я буду последним, меняющим это представление, и убедитесь, что система уважает мои изменения и не изменяет их позже.
Обновить:
Хотя я не считаю его актуальным; Код InflatorOnSteroids.kt
class InflatorOnSteriods(val appCompatActivity: AppCompatActivity) : LayoutInflaterFactory { override fun onCreateView(parent: View, name: String, context: Context, attrs: AttributeSet): View { var result: View if (TextUtils.equals(name, "DebugDrawerLayout")) { result = ImageView(context, attrs) } result = appCompatActivity.onCreateView(name, context, attrs) if (result == null) { // Get themed views from app compat result = appCompatActivity.delegate.createView(parent, name, context, attrs) } return result } }
По прошествии некоторого времени, устраняя проблемы с моим решением, я, наконец, смог добиться того, чего хотел с помощью заводского решения для инфлятора.
Сначала я создаю абстрактную деятельность, на которой настроен пользовательский инфлятор.
abstract class SteroidsActivity : AppCompatActivity() { var mInflater: LayoutInflater? = null abstract fun getActivityLayout(): Int override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mInflater = layoutInflater?.cloneInContext(this) LayoutInflaterCompat.setFactory(mInflater, InflaterOnSteroids(this)) setContentView(getActivityLayout()) } override fun getLayoutInflater(): LayoutInflater? { return mInflater } override fun getSystemService(name: String): Any? { if (name == LAYOUT_INFLATER_SERVICE) { if (mInflater == null) { mInflater = super.getSystemService(name) as LayoutInflater } return mInflater } return super.getSystemService(name) } }
Второе, что вам нужно сделать, это создать свой собственный завод инфлятора
class InflaterOnSteroids(appCompatActivity1: AppCompatActivity) : LayoutInflaterFactory { override fun onCreateView(parent: View?, name: String, context: Context, attrs: AttributeSet): View? { //Do stuff here and return a view return null } }
Проблема с моим кодом заключалась в том, что он всегда сбой с необычной ошибкой, что я не мог устранить неполадки, пока не понял, что мне нужно добавить ? после просмотра, так как я использую kotlin и родительский вид может быть нулевым 🙂
Счастливое программирование
Хорошую ссылку можно найти здесь