我正在开发新闻app用户可以下载视频和图像。
所以我开发了带有材料设计的不同片段的导航抽屉。但是当我点击图库(我显示下载的视频和图像)时,我会遇到一些问题,它会停留一段时间,然后打开片段。它只发生在特定的片段中,但不是全部。
请参阅Video here。
这是我的代码:
MainActivity.java
public class MainActivity extends AppCompatActivity implements FragmentDrawer.FragmentDrawerListener {
private static String TAG = MainActivity.class.getSimpleName();
private Toolbar mToolbar;
private FragmentDrawer drawerFragment;
TextView mTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
if (getSupportActionBar() != null)
{
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
mTitle = (TextView) mToolbar.findViewById(R.id.tv_toolbar_title);
drawerFragment = (FragmentDrawer)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
drawerFragment.setDrawerListener(this);
// display the first navigation drawer view on app launch
displayView(0);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
/* if (id == R.id.action_search) {
Toast.makeText(getApplicationContext(), "Search action is selected!", Toast.LENGTH_SHORT).show();
return true;
}*/
return super.onOptionsItemSelected(item);
}
@Override
public void onDrawerItemSelected(View view, int position) {
displayView(position);
}
private void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new HomeFragment();
title = getString(R.string.title_home);
mTitle.setText(title);
break;
case 1:
fragment = new GalleryFragment();
title = getString(R.string.title_gallery);
mTitle.setText(title);
break;
case 2:
fragment = new SettingFragment();
title = getString(R.string.title_setting);
mTitle.setText(title);
break;
case 3:
fragment = new AboutusFragment();
title = getString(R.string.title_aboutus);
mTitle.setText(title);
break;
case 4:
fragment = new ContactusFragment();
title = getString(R.string.title_contactus);
mTitle.setText(title);
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
if (getSupportActionBar() != null)
getSupportActionBar().setTitle(title);
}
}
}
FragmentDrawer.java
public class FragmentDrawer extends Fragment {
private static String TAG = FragmentDrawer.class.getSimpleName();
private RecyclerView recyclerView;
private ActionBarDrawerToggle mDrawerToggle;
private static DrawerLayout mDrawerLayout;
private NavigationDrawerAdapter adapter;
private View containerView;
private static String[] titles = null;
private static int[] ic_nav_drw = {R.drawable.ic_setting, R.drawable.gallery, R.drawable.setting, R.drawable.aboutus, R.drawable.contactus};
private FragmentDrawerListener drawerListener;
ImageView profile;
TextView tv_name;
public FragmentDrawer() {
}
public void setDrawerListener(FragmentDrawerListener listener) {
this.drawerListener = listener;
}
public static List<NavDrawerItem> getData() {
List<NavDrawerItem> data = new ArrayList<>();
// preparing navigation drawer items
for (int i = 0; i < titles.length; i++) {
NavDrawerItem navItem = new NavDrawerItem();
navItem.setTitle(titles[i]);
navItem.setIcon(ic_nav_drw[i]);
data.add(navItem);
}
return data;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// drawer labels
titles = getActivity().getResources().getStringArray(R.array.nav_drawer_labels);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflating view layout
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
tv_name = (TextView) layout.findViewById(R.id.tv_name);
profile = (ImageView) layout.findViewById(R.id.profile);
SharedPreferences settings = getActivity().getSharedPreferences("preference", 0);
String name = settings.getString("name","");
tv_name.setText(name);
profile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), "You click profile", Toast.LENGTH_SHORT).show();
}
});
adapter = new NavigationDrawerAdapter(getActivity(), getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
drawerListener.onDrawerItemSelected(view, position);
mDrawerLayout.closeDrawer(containerView);
}
@Override
public void onLongClick(View view, int position) {
}
}));
return layout;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActivity().invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
getActivity().invalidateOptionsMenu();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
toolbar.setAlpha(1 - slideOffset / 2);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
@Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public static interface ClickListener {
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
public interface FragmentDrawerListener {
public void onDrawerItemSelected(View view, int position);
}
}
activity_main.xml中
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
</LinearLayout>
<FrameLayout
android:id="@+id/container_body"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<fragment
android:id="@+id/fragment_navigation_drawer"
android:name="com.bicubic.botadnews.fragment.FragmentDrawer"
android:layout_width="@dimen/nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
tools:layout="@layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
fragment_navigation_drawer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<RelativeLayout
android:id="@+id/nav_header_container"
android:layout_width="match_parent"
android:layout_height="140dp"
android:layout_alignParentTop="true"
android:background="@color/colorPrimary">
<ImageView
android:id="@+id/profile"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerInParent="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_profile" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textColor="@color/white"
android:textSize="20sp"
android:layout_marginBottom="10dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/drawerList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/nav_header_container"
android:layout_marginTop="15dp" />
</RelativeLayout>
这是我的图库片段
Editted GalleryFragment.java
public class GalleryFragment extends Fragment implements View.OnClickListener {
View rootView;
static RecyclerView rv_video;
RecyclerView rv_image;
static List<File> videofiles;
static List<File> imagefiles;
Button bt_video, bt_image;
private static Context context ;
public GalleryFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_gallery, container, false);
rv_video = (RecyclerView) rootView.findViewById(R.id.rv_video);
rv_image = (RecyclerView) rootView.findViewById(R.id.rv_image);
bt_video = (Button) rootView.findViewById(R.id.bt_video);
bt_image = (Button) rootView.findViewById(R.id.bt_image);
bt_video.setBackgroundResource(R.color.colorAccent);
bt_video.setOnClickListener(this);
bt_image.setOnClickListener(this);
context = getActivity();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
rv_video.setLayoutManager(linearLayoutManager);
rv_video.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager1 = new LinearLayoutManager(getActivity());
rv_image.setLayoutManager(linearLayoutManager1);
rv_image.setHasFixedSize(true);
videofiles = new ArrayList<>();
imagefiles = new ArrayList<>();
new LoadOfflineData().execute();
rootView.post(new Runnable() {
@Override
public void run() {
new LoadOfflineData().execute();
}
});
// Inflate the layout for this fragment
return rootView;
}
public static class LoadOfflineData extends AsyncTask<Void, Void, Void> {
ProgressDialog progressBar;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar = new ProgressDialog(context);
progressBar.setMessage("Loading...");
progressBar.show();
}
@Override
protected Void doInBackground(Void... voids) {
String video_path = Environment.getExternalStorageDirectory().getPath() + "/Botad News/Videos";
Log.d("Files", "Path: " + video_path);
File checkFile = new File(video_path);
// videofiles = new ArrayList<>();
File[] files = new File[0];
if (checkFile.isDirectory()) {
File directory = new File(video_path);
files = directory.listFiles();
videofiles.addAll(Arrays.asList(files));
} else {
// Toast.makeText(getActivity(), "Folder not Found", Toast.LENGTH_SHORT).show();
Log.e(TAG, "doInBackground: folder not found" );
}
String image_path = Environment.getExternalStorageDirectory().getPath() + "/Botad News/Images";
Log.d("Files", "Path: " + image_path);
File checkFileImages = new File(image_path);
// imagefiles = new ArrayList<>();
File[] filesImage = new File[0];
if (checkFileImages.isDirectory()) {
File directory = new File(image_path);
filesImage = directory.listFiles();
imagefiles.addAll(Arrays.asList(filesImage));
} else {
// Toast.makeText(getActivity(), "Folder not Found", Toast.LENGTH_SHORT).show();
Log.e(TAG, "doInBackground: folder not found" );
}
Log.d("Files", "Size: " + files.length);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressBar.dismiss();
if (videofiles.size() > 0) {
RvGalleryVideoAdapter adapter = new RvGalleryVideoAdapter(videofiles, context);
rv_video.setAdapter(adapter);
} else {
Toast.makeText(context, "Data not found", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public void onDetach() {
super.onDetach();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_video:
bt_video.setBackgroundResource(R.color.colorAccent);
bt_image.setBackgroundResource(R.color.colorPrimary);
rv_image.setVisibility(View.GONE);
rv_video.setVisibility(View.VISIBLE);
if (videofiles.size() > 0) {
RvGalleryVideoAdapter adapter = new RvGalleryVideoAdapter(videofiles, getActivity());
rv_video.setAdapter(adapter);
} else {
Toast.makeText(getActivity(), "Data not found", Toast.LENGTH_SHORT).show();
}
break;
case R.id.bt_image:
bt_image.setBackgroundResource(R.color.colorAccent);
bt_video.setBackgroundResource(R.color.colorPrimary);
rv_image.setVisibility(View.VISIBLE);
rv_video.setVisibility(View.GONE);
if (imagefiles.size() > 0) {
RvGalleryImageAdapter adapter_image = new RvGalleryImageAdapter(imagefiles, getActivity());
rv_image.setAdapter(adapter_image);
} else {
Toast.makeText(getActivity(), "Data not found", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
}
答案 0 :(得分:1)
在AsyncTask
中,您正在访问片段的类字段!这实际上会阻止UI线程: - (
行
videofiles = new ArrayList<>();
imagefiles = new ArrayList<>();
不能在那里。您需要创建本地列表,将数据放入其中,然后在onPostExecute()
中返回。
首先替换
public class LoadOfflineData extends AsyncTask<Void, Void, Void> {
与
public static class LoadOfflineData extends AsyncTask<Void, Void, Void> {
这会在您需要更改的地方出现错误:-)
答案 1 :(得分:0)
我找到了答案。
当我使用内置类获取缩略图时,它在我的RecyclerAdapter中,所以设置它需要时间看我的
旧代码
Bitmap bmThumbnail;
//MICRO_KIND, size: 96 x 96 thumbnail
bmThumbnail = ThumbnailUtils.createVideoThumbnail(sdcard_path + "/Botad News/Videos/" + fileName, MediaStore.Images.Thumbnails.MICRO_KIND);
holder.img_main.setImageBitmap(bmThumbnail);
新代码正在使用滑动库,因此lib会自动处理我假设的线程。
BitmapPool bitmapPool = Glide.get(context).getBitmapPool();
int microSecond = 6000000;// 6th second as an example
VideoBitmapDecoder videoBitmapDecoder = new VideoBitmapDecoder(microSecond);
FileDescriptorBitmapDecoder fileDescriptorBitmapDecoder = new FileDescriptorBitmapDecoder(videoBitmapDecoder, bitmapPool, DecodeFormat.PREFER_ARGB_8888);
Glide.with(context)
.load(sdcard_path + "/Botad News/Videos/" + fileName)
.asBitmap()
.override(250,250)// Example
.videoDecoder(fileDescriptorBitmapDecoder)
.into(holder.img_main);
找到解决方案HERE....