0

I upgraded my code from ListView to RecyclerView however I'm facing a problem and I couldn't find an answer, I googled for days but no clue. Just bear with me Im new to it.

I managed to add OnclickListener witch works fine. But if i Run the app on Android TV, I don't Know how to achieved this:

1-on scroll , show where scroller is : like change background of the item

2-While Scrolling return the item url so i can send it to the player

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity">

<com.google.android.exoplayer2.ui.SimpleExoPlayerView
    android:id="@+id/playerView_step_video"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:use_controller="false"
    />

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="200dp"
    android:layout_height="match_parent"
    android:background="#60000000"
    android:overScrollMode="always"
    />

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/llItemView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:background="#80222222"
android:orientation="horizontal">

<LinearLayout android:id="@+id/th"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="3dip"
    android:layout_alignParentLeft="true"
    android:layout_marginRight="5dip"
    android:layout_alignParentStart="true"
    android:layout_marginEnd="5dip">

    <TextView
        android:id="@+id/tvId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="2dp"
        android:layout_marginRight="4dp"
        android:layout_gravity="center_vertical"
        android:textColor="#fff"
        android:textSize="12sp"
        android:layout_marginEnd="4dp" />
    <ImageView
        android:id="@+id/img_item"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:contentDescription="@string/app_name"
        android:scaleType="fitXY"
        android:src="@drawable/selection_band_overlay" />

    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="2dp"
        android:layout_marginLeft="4dp"
        android:layout_gravity="center_vertical"
        android:textColor="#fff"
        android:textSize="12sp"
        android:layout_marginStart="4dp" />

    <TextView
        android:id="@+id/tvUrl"
        android:layout_width="fill_parent"
        android:visibility="invisible"
        tools:visibility="invisible"
        android:layout_height="fill_parent" />

</LinearLayout>

item_custom.xml

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.RecyclerViewHolder> {

private List<ItemAdapter> dataModelList;
private Context context;
private OnClickListener OnClickListener;
private int selected_position = 0;



class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    TextView tvID;
    TextView tvName;
    TextView tvUrl;
    ImageView tvImg;
    RelativeLayout llItemView;
    OnClickListener OnclickListener;

        RecyclerViewHolder(View itemView, OnClickListener OnclickListener) {
            super(itemView);
            llItemView = itemView.findViewById(R.id.llItemView);
            tvID = itemView.findViewById(R.id.tvId);
            tvName = itemView.findViewById(R.id.tvName);
            tvUrl = itemView.findViewById(R.id.tvUrl);
            tvImg = itemView.findViewById(R.id.img_item);
            this.OnclickListener = OnclickListener;
            itemView.setOnClickListener(this);
        }

    @Override
    public void onClick(final View view) {
        if (getAdapterPosition() == RecyclerView.NO_POSITION) return;
        // Updating old as well as new positions
        notifyItemChanged(selected_position);
        selected_position = getAdapterPosition();
        notifyItemChanged(selected_position);
        TextView url = view.findViewById(R.id.tvUrl);
        OnClickListener.OnUrlClickListener((String) url.getText());
        //you will need to do something similar to this listener for all focusable things


    }
}





    //create constructor with list
    ListAdapter(List<ItemAdapter> dataModelList, OnClickListener OnClickListener) {
        this.dataModelList = dataModelList;
        this.OnClickListener = OnClickListener;
    }

    @NonNull
    @Override
    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        RecyclerViewHolder viewHolder;
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_custom, parent, false);
        viewHolder = new RecyclerViewHolder(view, OnClickListener);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, final int position) {

        holder.tvID.setText(String.valueOf(dataModelList.get(position).getId()));
        holder.tvName.setText(dataModelList.get(position).getName());
        holder.tvUrl.setText(dataModelList.get(position).getUrl());
        Glide.with(context)
                .load(dataModelList.get(position).getImg())
                .apply(new RequestOptions()
                        .override(100, 100)
                        .transforms(new CenterCrop(), new FitCenter(),  new RoundedCorners(14)))
                .into(holder.tvImg);
        holder.itemView.setBackgroundColor(selected_position == position ? Color.GREEN : Color.TRANSPARENT);



    }

    @Override
    public long getItemId(int position) {

        return super.getItemId(position);
    }

    @Override
    public int getItemCount() {
        return dataModelList.size();
    }

public interface OnClickListener {
    void OnUrlClickListener(String url);
}


}

ListAdapter.class


public class MainActivity extends AppCompatActivity implements ListAdapter.OnClickListener {
private List<ItemAdapter> dataModelList;
RecyclerView recyclerView;
SimpleExoPlayer player;
LinearLayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();
    // Instantiate the recyclerView
    recyclerView = findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
    recyclerView.setLayoutManager(layoutManager);

    setData();
    setDataToRecyclerView();
    player = new SimpleExoPlayer.Builder(this).build();
    final PlayerView playerView = findViewById(R.id.playerView_step_video);
    playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
    playerView.setPlayer(player);
    player.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
    recyclerView.setVisibility(View.INVISIBLE);
    final RelativeLayout playerV = findViewById(R.id.parent);
    playerV.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            int visibility = recyclerView.getVisibility();
            if (visibility == 0){
                recyclerView.setVisibility(View.INVISIBLE);
            }else{
                recyclerView.setVisibility(View.VISIBLE);
            }
        }
    });
    recyclerView.setFocusable(true);
    recyclerView.setSelected(true);
}

private void setData() {
    String glaras = null;
    try {
        glaras = new glarab().execute().get();
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    int i = 0;
    dataModelList = new ArrayList<>();
    try {

        String x = new JSONParser().execute().get();
        JSONObject jsonObject = new JSONObject(x);
        Iterator<String> keys = jsonObject.keys();
        while(keys.hasNext()) {
            i += 1;
            String number = "#" + i;
            String key = keys.next();
            JSONArray channels_pics = (JSONArray) jsonObject.get(key);
            JSONObject items = (JSONObject) channels_pics.get(0);
            String stream = (String) items.get("url");
            if(stream.contains("7777")){
                stream = stream+glaras;
            }
            if(stream.length() < 1){
                stream = "https://content.jwplatform.com/manifests/yp34SRmf.m3u8";
            }
            dataModelList.add(new ItemAdapter(number, key, stream, (String) items.get("logo")));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
private void setDataToRecyclerView() {
    ListAdapter adapter = new ListAdapter(dataModelList, this);
    recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
    recyclerView.setAdapter(adapter);
}


public void OnUrlClickListener(String url) {
    final HttpDataSource.Factory dataSourceFactory = new DefaultHttpDataSourceFactory("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36");
    HlsMediaSource hlsMediaSource =
            new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(url));
    player.prepare(hlsMediaSource);
    player.setPlayWhenReady(true);

}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    final int keyCode = event.getKeyCode();
    if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) {
        if (event.getAction() == KeyEvent.ACTION_UP ) {
            recyclerView.setVisibility(View.VISIBLE);         
            return true;
        }
    }


    //System.out.println(keyCode);
    if(keyCode == 22 || keyCode == 21 ){
        recyclerView.setVisibility(View.INVISIBLE);
    }
    return super.dispatchKeyEvent(event);
}

@Override
public void onBackPressed() {
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    MainActivity.this.finish();
    System.exit(0);
}

@Override
protected void onUserLeaveHint()
{
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    MainActivity.this.finish();
    System.exit(0);
}
}

So again with D-pad I'm able to scroll but I don't know what item is selected, would be nice to change the background so I know what item.

Previously, with listView, I was able to use OnItemSelectedListener, changing background of selected Item, getting the string, just by scrolling item by item. this is what I need with RecyclerView. If any one can modified my code to make it work and explain how that would be nice. Thank you So much in Advance

2 Answers2

0

You can enter Toast onBindViewHolder like the following code or you can place a background color while click.

@Override
public void onBindViewHolder(@NonNull MyViewHolder myHolder, final int position) {

    myHolder.txtName.setText(countryList[position]);
    myHolder.imgCountry.setImageResource(imgList[position]);
    // implement setOnClickListener event on item view.
    myHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // display a toast with person name on item click
            Toast.makeText(context, countryList[position], Toast.LENGTH_SHORT).show();
        }
    });

}
  • it doesn't respond to my question i'm looking for how to implement OnitemSelectedListener for RecyclerView like the one for listview.By the way, I read that the best way for OnclickListener is to avoid using it within onBindViewHolder. If the code you showed me is a part of your app, you may implement Interface is better – Tarik Cisco Apr 07 '20 at 11:59
0

You have to make another xml file in drawable for highlighting the scroll like following e-g

(border.xml)

<item android:state_pressed="true" >
    <shape android:shape="rectangle" >

        <stroke android:width="3dip" android:color="#ffcc00" />
        <solid android:color="#F39000"/>
    </shape>
</item>

<item android:state_focused="true">
    <shape android:shape="rectangle" >

        <stroke android:width="3dip"  android:color="#F39000"
            />
        <solid android:color="#fff"/>

    </shape>
</item>
<item>
    <shape android:shape="rectangle">
        <solid android:color="@color/gray"/>
    </shape>
</item>

now add following two properties to your parent layout of your recycler view adpter xml:

android:focusable="true"

android:background="@drawable/border"

By doing this you will get the background color changed on focus and on button pressed.

2-)Now for getting url and then pass it to the player you will have to do this in click listener which would be in onBindViewHolder, you just get the url and pass it on just like this:

@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

           String urlstring =url.get( position );
            Intent intent = new Intent(context, Player.class);
            intent.putExtra( "key", urlstring );

            context.startActivity(intent);
        }
    });


}

Hope you will get your desire answer.

Nikos Hidalgo
  • 3,666
  • 9
  • 25
  • 39