Постараюсь преподнести вопрос корректно (открыт для замечаний/правок).
Начну пожалуй с начала. Есть кнопка по нажатию на которую открывается диалог. В диалоге пользователь может вставить ссылку из vimeo и youtube.
После того, как ссылка вставлена в поле диалога и нажата кнопка "OK", в методе getIdUrl вытаскивается id из ссылки, после чего добавляется сама картинка из видео(preview) - пользователь(грубо говоря) видит как добавилась картинка из этого видео(следовательно видео загружено).
На данный момент, приложение реализовано так, что пользователь может добавлять n-ое кол-во видео(с одинаковыми ссылками), что само собой неприемлемо.
Задача заключается в поиске решения данной проблемы, а именно:
Добавить возможность для пользователя добавления не более 10 файлов.
Если ссылка повторяется(url видео), не добавлять его.
Отрывок диалога:
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Toast.makeText(getContext(), "ОК", Toast.LENGTH_SHORT).show();
String string = input.getText().toString();
getIdUrl(string, pos);
}
И часть реализации метода getIdUrl для youtube:
void getIdUrl(String url, int position) {
String video_id = "";
String expression = "";
if (url != null && url.trim().length() > 0 && url.matches(".*\\byoutube\\b.*")) {
expression = "^.*((youtu.be" + "\\/)" + "|(v\\/)|(\\/u\\/w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#\\&\\?]*).*";
CharSequence input = url;
Pattern pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {
String groupIndex1 = matcher.group(7);
if (groupIndex1 != null && groupIndex1.length() == 11)
video_id = groupIndex1;
}
ImageUpload imageUpload = new ImageUpload();
imageUpload.setLoadImage(true);
OutputMetadata outputMetadata = new OutputMetadata();
outputMetadata.setVideoUrl("http://img.youtube.com/vi/" + video_id + "/0.jpg");
outputMetadata.setFilename("http://img.youtube.com/vi/" + video_id + "/0.jpg");
imageUpload.setOutputMetadata(outputMetadata);
controlList.get(position).getImageUploads().add(imageUpload);
adapterForm.notifyDataSetChanged();
Дополнительно к разбору:
Модель VideoUpload
public class VideoUpload {
@SerializedName("id")
@Expose
private String id;
@SerializedName("videoUrl")
@Expose
String videoUrl;
@SerializedName("user_portrait_huge")
@Expose
private String userPortraitHuge;
@SerializedName("url")
@Expose
private String url;
public String getUserPortraitHuge() {
return userPortraitHuge;
}
Прописаны все get'ры и set'ры.
Метод contains(во фрагменте)
public boolean contains(VideoUpload newVideoUpload) {
for (VideoUpload videoUpload : videoUploads) {
if (videoUpload.getUrl().equals(newVideoUpload.getUrl()))
return true;
}
return false;
}
Ответ
Постановка задачи:
По ссылке на видео с youtube.com или vimeo.com получить превью видео и отобразить его в списке на экране.
При этом:
Максимально можно добавить 10 видео;
Не добавлять уже существующие видео.
Превью можно добавить по трем типам ссылок:
https://www.youtube.com/watch?v=XXXXXXXXXXX
https://youtu.be/XXXXXXXXXXX
https://vimeo.com/XXXXXXXXX
Решение:
Создаем activity_video_preview.xml
Создаем item_video_preview.xml
Создаем (для удобства) интерфейс VideoTypes
public interface VideoTypes {
int TYPE_UNKNOWN = 0;
int TYPE_YOUTUBE = 1;
int TYPE_VIMEO = 2;
}
Создаем класс модели данных VideoPreview
public class VideoPreview {
private String mVideoLink;
private String mPreviewLink;
public VideoPreview(String videoLink, String previewLink) {
mVideoLink = videoLink;
mPreviewLink = previewLink;
}
public String getVideoLink() {
return mVideoLink;
}
public String getPreviewLink() {
return mPreviewLink;
}
}
Создаем класс VideoMethods для обработки ссылок на видео:
public class VideoMethods implements VideoTypes {
public static int getLinkType(String link) {
Pattern pattern = Pattern.compile("^https:\\/\\/www\\.(youtube\\.com)\\/watch\\?v=[\\w-]{11}$|^https:\\/\\/(youtu\\.be)\\/[\\w-]{11}$|^https:\\/\\/(vimeo\\.com)\\/[0-9]*$");
Matcher matcher = pattern.matcher(link);
if (!matcher.matches())
return TYPE_UNKNOWN;
for (int i=1; i<=matcher.groupCount(); i++) {
if (matcher.group(i) != null) {
switch (i) {
case 1:
case 2:
return TYPE_YOUTUBE;
case 3:
return TYPE_VIMEO;
default:
return TYPE_UNKNOWN;
}
}
}
return TYPE_UNKNOWN;
}
public static String getId(String link) {
Pattern pattern = Pattern.compile("^https:\\/\\/www\\.youtube\\.com\\/watch\\?v=([\\w-]{11})$|^https:\\/\\/youtu\\.be\\/([\\w-]{11})$|^https:\\/\\/vimeo\\.com\\/([0-9]*)$");
Matcher matcher = pattern.matcher(link);
matcher.matches();
for (int i=1; i<=matcher.groupCount(); i++) {
if (matcher.group(i) != null) {
return matcher.group(i);
}
}
return null;
}
}
Адаптер для RecyclerView
public class DataAdapter extends RecyclerView.Adapter
public DataAdapter(Context context) {
mContext = context;
mItems = new ArrayList<>();
}
@Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_video_preview, viewGroup, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.mPreviewLinkTextView.setText(mItems.get(i).getVideoLink());
viewHolder.mPreviewLinkPreviewTextView.setText(mItems.get(i).getPreviewLink());
Picasso.with(mContext).load(mItems.get(i).getPreviewLink()).resize(120, 90).into(viewHolder.mPreviewImageView);
}
@Override
public int getItemCount() {
return mItems.size();
}
public void addItem(VideoPreview videoPreview) {
mItems.add(videoPreview);
notifyDataSetChanged();
}
public boolean contains(VideoPreview newVideoPreview) {
for (VideoPreview videoPreview : mItems) {
if (videoPreview.getVideoLink().equals(newVideoPreview.getVideoLink()))
return true;
}
return false;
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView mPreviewImageView;
TextView mPreviewLinkTextView;
TextView mPreviewLinkPreviewTextView;
public ViewHolder(View view) {
super(view);
mPreviewImageView = (ImageView) view.findViewById(R.id.item_video_preview_image_view);
mPreviewLinkTextView = (TextView) view.findViewById(R.id.item_video_preview_link_text_view);
mPreviewLinkPreviewTextView = (TextView) view.findViewById(R.id.item_video_preview_link_preview_text_view);
}
}
}
Ну и, наконец, VideoPreviewActivity
public class VideoPreviewActivity extends AppCompatActivity implements VideoTypes {
private RecyclerView mVideoPreviewRecyclerView;
private EditText mAddEditText;
private Button mAddButton;
private OkHttpClient httpClient;
private DataAdapter mDataAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_preview);
mVideoPreviewRecyclerView = (RecyclerView) findViewById(R.id.video_preview_recycler_view);
mAddEditText = (EditText) findViewById(R.id.add_edit_text);
mAddButton = (Button) findViewById(R.id.add_button);
mVideoPreviewRecyclerView = (RecyclerView)findViewById(R.id.video_preview_recycler_view);
mVideoPreviewRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
mVideoPreviewRecyclerView.setLayoutManager(layoutManager);
mDataAdapter = new DataAdapter(getApplicationContext());
mVideoPreviewRecyclerView.setAdapter(mDataAdapter);
httpClient = new OkHttpClient();
mAddButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mDataAdapter.getItemCount() == 10) {
Toast.makeText(getApplicationContext(), "You can not add more than 10 videos!", Toast.LENGTH_SHORT).show();
return;
}
String videoLink = mAddEditText.getText().toString();
int videoType = VideoMethods.getLinkType(videoLink);
if (videoType == TYPE_UNKNOWN) {
Toast.makeText(getApplicationContext(), "Incorrect link!", Toast.LENGTH_SHORT).show();
return;
}
mAddEditText.getText().clear();
InputMethodManager inputMethodManager = (InputMethodManager) VideoPreviewActivity.this.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(VideoPreviewActivity.this.getCurrentFocus().getWindowToken(), 0);
String videoId = VideoMethods.getId(videoLink);
switch (videoType) {
case TYPE_YOUTUBE:
VideoPreview videoPreview = new VideoPreview(videoLink, "http://img.youtube.com/vi/" + videoId + "/1.jpg");
if (!mDataAdapter.contains(videoPreview)) {
mDataAdapter.addItem(videoPreview);
mVideoPreviewRecyclerView.scrollToPosition(mDataAdapter.getItemCount()-1);
} else {
Toast.makeText(getApplicationContext(), "This video already exists!", Toast.LENGTH_SHORT).show();
}
break;
case TYPE_VIMEO:
try {
getVimeoPreview(videoLink, videoId);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Something going wrong!", Toast.LENGTH_SHORT).show();
}
break;
}
}
});
}
public void getVimeoPreview(final String videoLink, final String videoId) throws Exception {
Request request = new Request.Builder()
.url("http://vimeo.com/api/v2/video/" + videoId + ".xml")
.build();
httpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(getApplicationContext(), "Something going wrong!", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String s = response.body().string();
Pattern p = Pattern.compile("
runOnUiThread(new Runnable() {
@Override
public void run() {
VideoPreview videoPreview = new VideoPreview(videoLink, m.group(1));
if (!mDataAdapter.contains(videoPreview)) {
mDataAdapter.addItem(videoPreview);
mVideoPreviewRecyclerView.scrollToPosition(mDataAdapter.getItemCount()-1);
} else {
Toast.makeText(getApplicationContext(), "This video already exists!", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
}
Не забывает добавить в build.gradle
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.picasso:picasso:2.5.2'
В итоге получаем:
Комментариев нет:
Отправить комментарий