How can I display panel states of SlidingUpPanel in Kotlin?
I want to use https://github.com/umano/AndroidSlidingUpPanel library, following this tutorial:
http://www.devexchanges.info/2015/05/making-sliding-up-panel-like-google.html
and the result should look like this:
https://www.youtube.com/watch?v=g464fp-2dQU
The code in Java from tutorial link:
private SlidingUpPanelLayout.PanelSlideListener onSlideListener() {
return new SlidingUpPanelLayout.PanelSlideListener() {
#Override
public void onPanelSlide(View view, float v) {
textView.setText("panel is sliding");
}
#Override
public void onPanelCollapsed(View view) {
textView.setText("panel Collapse");
}
#Override
public void onPanelExpanded(View view) {
textView.setText("panel expand");
}
#Override
public void onPanelAnchored(View view) {
textView.setText("panel anchored");
}
#Override
public void onPanelHidden(View view) {
textView.setText("panel is Hidden");
}
};
}
The converted code from Java to Kotlin (I put toast from anko library instead of textView):
private fun onSlideListener(): SlidingUpPanelLayout.PanelSlideListener {
return object : SlidingUpPanelLayout.PanelSlideListener {
override fun onPanelSlide(view: View, v: Float) {
toast("panel is sliding")
}
override fun onPanelCollapsed(view: View) {
toast("panel Collapse")
}
override fun onPanelExpanded(view: View) {
toast("panel expand")
}
override fun onPanelAnchored(view: View) {
toast("panel anchored")
}
override fun onPanelHidden(view: View) {
toast("panel is Hidden")
}
}
}
In Java code, in onCreate method, I have:
slidingLayout.setPanelSlideListener(onSlideListener());
which doesn't seems to work in Kotlin, because the methods I have are Click, Drag, Hover, Key and Touch (listeners).
I guess other good approach could be to implement
SlidingPaneLayout.PanelSlideListener
on my class, but I still couldn't make it work.
Any solution to find up if the panel is displayed or hidden in Kotlin?
You need to load up the Slidinglayout.
private lateinit var slidingLayout: SlidingUpPanelLayout
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.activity_main, container, false).also {
slidingLayout = it.findViewById(R.id.sliding_Layout)
}
}
than you check for the PanelState
if (slidingLayout.panelState == SlidingUpPanelLayout.PanelState.HIDDEN)
You also have the states ANCHORED, EXPANDED, COLLAPSED, DRAGGING
If you want to set up the Listener in Kotlin I have done it like This.
slidingLayout.addPanelSlideListener(object : SlidingUpPanelLayout.PanelSlideListener {
override fun onPanelSlide(panel: View?, slideOffset: Float) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onPanelStateChanged(panel: View?, previousState: SlidingUpPanelLayout.PanelState?, newState: SlidingUpPanelLayout.PanelState?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
Related
How can I implement android media controls for the Notification Center when using MediaPlayer?
I tried to use the offical documentation right here and this article but I couldn't implement it correctly.
I tried to call this method when I start my media player mediaPlayer?.start(), but nothing is showing up in the notification center:
val mSession: MediaSession by lazy { MediaSession(requireContext(), "MusicService") }
fun createMediaControls() {
mSession.isActive = true
mSession.setCallback(object : MediaSession.Callback() {
override fun onMediaButtonEvent(mediaButtonIntent: Intent): Boolean {
print("onMediaButtonEvent called: $mediaButtonIntent")
return false
}
override fun onPause() {
print("onPause called (media button pressed)")
super.onPause()
}
override fun onPlay() {
print("onPlay called (media button pressed)")
super.onPlay()
}
override fun onStop() {
print("onStop called (media button pressed)")
super.onStop()
}
})
mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS or MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS)
mSession.setMetadata(
MediaMetadata.Builder()
.putString(MediaMetadata.METADATA_KEY_TITLE, "titleee")
.putString(MediaMetadata.METADATA_KEY_ARTIST, "artist")
.putString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, "albumArtUri")
.build()
)
}
To prevent an EditText from receiving content from the clipboard, I disable the long click and text selectable, plus cleared the action mode menu:
EditText editText = findViewById(R.id.et);
editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public void onDestroyActionMode(ActionMode mode) {
}
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
});
editText.setTextIsSelectable(false);
editText.setLongClickable(false);
The problem is that I keep receiving clipboard suggestions that when selected are pasted to my EditText. How can I disable this or simply ignore this pasted content?
To disable all types of copy past from keyboard, keyboard extension, Action Menu and any other type you can add a textChangeListener to your EditText and check in the method beforeTextChanged like the follow:
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
if (after - count > 1) {
editText.setText(s)
editText.setSelection(s.toString().length)
}
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int){}
})
this solution works if someone past more than one character at the time. Good luck
I am using a Handler to display a timer in RecyclerView list item. When I press back the Activity that hosts the RecyclerView is completely destroyed, the Handler() still running in the background. The handler is created and initiated in ViewHolder. Is there any way to remove the callbacks from handler from ViewHolder itself?
My ViewHolder sample code
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), CustomRunnable.CustomRunnableListener{
private val handler = Handler()
lateinit var customRunnable: CustomRunnable //custom runnable for my timer logic
fun bind(position: Int, listModelClass: ModelClass?){
if(someCondition){
customRunnable = CustomRunnable(handler, this, textView, listModelClass)
handler.postDelayed(customRunnable, 1000)
}
}
override fun onTimerFinish(listModelClass: ModelClass) {
// I get this call back when the timer finishes
handler.removeCallbacks(customRunnable)
}
}
As per my knowledge, there is no method on adapter that is called when RecyclerView is detached from activity.
Try creating a timer object or a list of objects in your BaseActivity or Application Class and after pressing onBack run a method that will stop that timer or timers.
//Declare timer
CountDownTimer cTimer = null;
//start timer function
void startTimer() {
cTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
};
cTimer.start();
}
//cancel timer
void cancelTimer() {
if(cTimer!=null)
cTimer.cancel();
}
You can do it onDestory() of activity
handler.removeCallbacksAndMessages(null);
Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed.
if your Activity extended from androidx.activity.ComponentActivity, you can do this easily, just bind the lifecycle event then the super class would done their job as your desired, the sample code like below:
internal class SampleViewHolder(
private val activity: TheActivity,
view: View
) : RecyclerView.ViewHolder(view) {
fun bind(item: SampleInfo, position: Int) {
val view = itemView
...
bindLifecycle()
}
fun onViewRecycled() {
itemView.imv_sample.onViewRecycled(sampleAdapter.playStateStore)
activity.lifecycle.removeObserver(lifecycleObserver)
}
private val lifecycleObserver = object : LifecycleObserver {
#OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private fun onDestroy() {
MLog.info(TAG, "receive destroy event")
itemView.imv_sample.onHostActivityDestroyed()
}
}
private fun bindLifecycle() {
activity.lifecycle.run {
MLog.info(TAG, "success bind lifecycle")
addObserver(lifecycleObserver)
}
}
}
When the activity is destroyed, set the list adapter to null. This will make sure onViewDetachedFromWindow is called for all the views in list when the activity is destroyed.
#Override
public void onDestroy() {
mList.setAdapter(null);
super.onDestroy();
}
And then you can remove the callbacks from the handler running inside the viewHolder. This requires you to save the handler reference inside your viewHolder.
#Override
public void onViewDetachedFromWindow(#NonNull PurchaseItemViewHolder holder) {
if (holder.handler != null) {
holder.handler.removeCallbacksAndMessages(null);
}
super.onViewDetachedFromWindow(holder);
}
This question already has answers here:
Android : How to set onClick event for Button in List item of ListView
(10 answers)
Closed 4 years ago.
I'm making an inventory tracker app for Android for a practice project. I use SQLite for the storage and my ListView displays the contents of the database using a CursorAdapter. I use CursorLoader to fetch the data from the database
Each row in my ListView has a couple of TextViews and a Button. I plan to use the Button to decrement the quantity column/property of the selected item in the database.
Where do I setup the button OnClick listener? In my Activity class or my CursorAdapter class' bindView()?
Also how can I detect which row the button was pressed on from the button click?
I've already used the ListView's onItemClickListener to send the user to a detailed Activity that display more info about the current row. That had an id argument that gets passed. So I'm finding an equivalent that I can use for the buttons I put on each row.
Look the following. I used the Custom adapter to add the onItemClickListener:
private class MyListAdapter(val ctx: Context, val values: List<MyListInformatin>) : ArrayAdapter<MyListInformatin>(ctx, -1, values) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val rowView = inflater.inflate(R.layout.item_my_layout, parent, false)
rowView.setOnClickListener {
val detailsActivity = Intent(ctx, DetailsActivity::class.java)
detailsActivity.putExtra(DetailsActivity.ROUTE_NUMBER_PARAM, values.get(position).routeNumber)
val bundle = Bundle()
bundle.putParcelable(detailsActivity.ROUTE_NO_STRUCTURE_PARAM, values.get(position).strucutre)
detailsActivity.putExtra(detailsActivity.PARAM_BUNDLE, bundle)
ctx.startActivity(detailsActivity)
}
return rowView
}
}
You can create an interface inside your adapter and a declare a fucntion in this interfae like ** void itemClick(int position)** and implement that interface in your activity
for void itemClick(int position) method :- Define it on
holder.setOnClickListener() block like -
viewHolder.button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (yourInterface != null) {
yourInterface.itemClick(position);
}
}
});
For detailed description refer the below link -
https://www.c-sharpcorner.com/UploadFile/9e8439/create-custom-listener-on-button-in-listitem-listview-in-a/
This question has been answered already, you need to setup your list items as not clickable and manually listen for onClick events of buttons, see a detailed answer here: Android : How to set onClick event for Button in List item of ListView
public class MyCustomAdapter extend Adapter {
private MyOnClickListener mListener;
#Override
public View getView(int position, View view, ViewGroup parent)
{
...
// Your view
mContainer.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mListener.onWholeItemClick(position);
}
});
// Your button
mButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mListener.onButtonClick(position);
}
});
}
public void setListener(MyOnClickListener listener) {
this.mListener = listener;
}
// Listener interface
public interface MyOnClickListener() {
void onWholeItemClick(int position); // Can pass data as a parametter
void onButtonClick(int position);
}
}
public class MyActivity extend Activity implement MyOnClickListener() {
...
#Override
public void onCreate(...) {
mAdapter = new MyCustomAdapter(this);
mAdapter.setListener(this); // Pass the listener to adapter
}
#Override
public void onWholeItemClick(int position) {
//
}
#Override
public void onButtonClick(int position) {
//
}
}
That how you can fully hanhle click events
In onBindViewHolder give a tag to that button. that tag can be the position of item or the item itself . ( tag can be object )
override fun onBindViewHolder(holder: ItemHolder, position: Int) {
CUSTOMMODEL item = items[position];
...
holder.button.setTag(item);
//OR
holder.button.setTag(position);
...
holder.button.setOnClickListener(clickListener);
}
in your onClick(View view) method, get tag from the view and you can understand which item is clicked.
I want to know how to add multiple click events to buttons defined in XML, as previously, in Java, we implemented View.onClickListener interface and did the rest of the work in onClick method.
Example:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.oneButton:
// do your code
break;
case R.id.twoButton:
// do your code
break;
case R.id.threeButton:
// do your code
break;
default:
break;
}
}
I'm making a basic calculator app with the new Kotlin but it seems Kotlin has no such provisions, instead my code looks too long and verbose, as I'm attaching events to all buttons individually.
Can someone tell me how to do the same way in Kotlin? Thanks
For multiple onClickListeners in kotlin (version:1.1.60), the following helped me. Hope it'll be useful to someone else too.
Implement OnClickListener to activity like:
class YourActivity : AppCompatActivity(), View.OnClickListener
set your button in onCreate():
val button = findViewById<Button>(R.id.buttonId)
and assign onclick to the button in onCreate():
button.setOnClickListener { onClick(button) }
and in the override method of onClick() :
override fun onClick(v: View) {
when (v.id) {
R.id.buttonId -> { //your code }
..
..
..
else -> { //your code }
}
}
Yes, in Kotlin you can do it like this:
view.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
when(v?.id) {
R.id.imgBack -> {/* do your code */}
R.id.twoButton -> {/* do your code */}
R.id.threeButton -> {/* do your code */}
else -> {/* do your code */}
}
}
}
You can try this following code:
class Testing:AppCompatActivity(), View.OnClickListener {
private val mButton1:Button
private val mButton2:Button
protected fun onCreate(savedInstanceState:Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_testing)
mButton1 = findViewById(R.id.btn_click) as Button
mButton2 = findViewById(R.id.btn_click1) as Button
mButton1.setOnClickListener(this)
mButton2.setOnClickListener(this)
}
fun onClick(view:View) {
when (view.getId()) {
R.id.btn_click -> {
Toast.makeText(this, "button 1", Toast.LENGTH_SHORT).show()
}
R.id.btn_click1 -> {
Toast.makeText(this, "button 2", Toast.LENGTH_SHORT).show()
}
else -> {}
}
}
}
I hope this is help you.
First of all implement OnClickListener in your Activity, like
class MainActivity : Activity , OnClickListener
then override its implementation like
func onClick(v:View) {
//use when here like
case R.id.youview -> {
// do your work on click of view
}
Don't forgot to set clicklistener on your View.
yourView.setOnClickListener(this)
Or for better understanding go step by step -
Implement OnClickListener in your Activity.
Compiler will ask you to implement overrided methods. Implement those.
Copy paste your java code which you wrote inside onClick method, that can be converted by kotlin itself or write down when conditions.
This code worked for me:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
imgBack.setOnClickListener(this)
twoButton.setOnClickListener(this)
threeButton.setOnClickListener(this)
}
override fun onClick(view:View) {
when (view.id) {
R.id.imgBack -> {
Toast.makeText(this, "imgBack", Toast.LENGTH_SHORT).show()
}
R.id.twoButton -> {
Toast.makeText(this, "twoButton", Toast.LENGTH_SHORT).show()
}
else -> {}
}
}
Don't forget implement View.OnClickListener in your class.
you can create anonymous object from an inteface View.ClickListener and pass it to setOnClickListener function
private val clickListener = View.OnClickListener { p0 ->
when (p0.id) {
....
}
}
... setOnClickListener(clickListener)
Try below like this.
public class MainActivity extends Activity implements View.OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button xyz = (Button) findViewById(R.id.xyz);
xyz.setOnClickListener(this);
}
#Override
public void onClick(View v) {
}}
More detailed information at https://androidacademic.blogspot.in/2016/12/multiple-buttons-onclicklistener-android.html